Как я могу заменить устаревший метод this.stop() в ThreadGroup

#java #multithreading #deprecated #threadgroup

#java #многопоточность #устаревший #threadgroup

Вопрос:

Я работаю над проектом обновления версии Java, и я нахожусь на работе, где мне нужно заменить устаревшие методы.

this.stop();

Код, используемый этим методом, находится в ::

ThreadedTestGroup.java::

     package utmj.threaded;

import junit.framework.*;
public class ThreadedTestGroup extends ThreadGroup {
    private Test test;
    private TestResult testResu<

    public ThreadedTestGroup(Test test) {
        super("ThreadedTestGroup");
        this.test = test;
    }


    public void interruptThenStop() {
        this.interrupt();
        if (this.activeCount() > 0) {
        this.stop(); // For those threads which won't interrupt
        }
    }


    public void setTestResult(TestResult result) {
        testResult = resu<
    }


    public void uncaughtException(Thread t, Throwable e) {
        if (e instanceof ThreadDeath) {
            return;
        }
        if (e instanceof AssertionFailedError) {
            testResult.addFailure(test, (AssertionFailedError) e);
        } else {
            testResult.addError(test, e);
        }
        this.interruptThenStop();
    }
}
  

CobcyrrentTestCase.java

     package utmj.threaded;

import java.util.*;

import junit.framework.*;

/
public class ConcurrentTestCase extends TestCase {
    private TestResult currentResu<
    private ThreadedTestGroup threadGroup;
    private Hashtable threads = new Hashtable();
    private boolean deadlockDetected = false;
    private Vector checkpoints = new Vector();

    class ConcurrentTestThread extends Thread {
        private volatile boolean hasStarted = false;
        private volatile boolean hasFinished = false;
        ConcurrentTestThread(
            ThreadGroup group,
            Runnable runnable,
            String name) {
            super(group, runnable, name);
        }
        public void run() {
            hasStarted = true;
            super.run();
            finishThread(this);
        }
    }

    public ConcurrentTestCase(String name) {
        super(name);
    }

    public ConcurrentTestCase() {
        super();
    }

    protected void addThread(String name, final Runnable runnable) {
        if (threads.get(name) != null) {
            fail("Thread with name '"   name   "' already exists");
        }
        ConcurrentTestThread newThread =
            new ConcurrentTestThread(threadGroup, runnable, name);
        threads.put(name, newThread);
    }

    public synchronized void checkpoint(String checkpointName) {
        checkpoints.addElement(checkpointName);
        this.notifyAll();
    }

    public boolean checkpointReached(String checkpointName) {
        return checkpoints.contains(checkpointName);
    }

    public boolean deadlockDetected() {
        return deadlockDetected;
    }

    private synchronized void finishThread(ConcurrentTestThread thread) {
        thread.hasFinished = true;
        this.notifyAll();
    }

    private ConcurrentTestThread getThread(String threadName) {
        return (ConcurrentTestThread) threads.get(threadName);
    }

    /**
     * Returns true if the thread finished normally, i.e. was not inerrupted or stopped
     */
    public boolean hasThreadFinished(String threadName) {
        ConcurrentTestThread thread = this.getThread(threadName);
        if (thread == null) {
            fail("Unknown Thread: "   threadName);
        }
        return thread.hasFinished;
    }

    public boolean hasThreadStarted(String threadName) {
        ConcurrentTestThread thread = this.getThread(threadName);
        if (thread == null) {
            fail("Unknown Thread: "   threadName);
        }
        return thread.hasStarted;
    }

    private void interruptAllAliveThreads() {
        threadGroup.interruptThenStop();
    }

    /**
     * Wait till all threads have finished. Wait maximally millisecondsToWait.
     * Should only be called after startThreads().
     */
    protected void joinAllThreads(long millisecondsToWait) {
        Enumeration enum1 = threads.elements();
        long remainingMilliseconds = millisecondsToWait;
        while (enum1.hasMoreElements()) {
            long before = System.currentTimeMillis();
            ConcurrentTestThread each =
                (ConcurrentTestThread) enum1.nextElement();
            try {
                each.join(remainingMilliseconds);
            } catch (InterruptedException ignored) {
            }
            long spent = System.currentTimeMillis() - before;
            if (millisecondsToWait != 0) {
                remainingMilliseconds = remainingMilliseconds - spent;
                if (remainingMilliseconds <= 0) {
                    deadlockDetected = true;
                    break;
                }
            }
        }
    }

    public void joinThread(String threadName) throws InterruptedException {
        this.joinThread(threadName, 0);
    }

    public void joinThread(String threadName, long millisecondsToTimeout)
        throws InterruptedException {
        ConcurrentTestThread thread = this.getThread(threadName);
        if (thread == null) {
            fail("Unknown Thread: "   threadName);
        }
        thread.join(millisecondsToTimeout);
    }

    /**
     * Stores the current result to be accessible during the test
     */
    public void run(TestResult result) {
        currentResult = resu<
        super.run(result);
    }

    protected void setUp() throws Exception {
        threadGroup = new ThreadedTestGroup(this);
    }

    /**
     * Sleep and ignore interruption
     */
    public void sleep(long milliseconds) {
        try {
            Thread.sleep(milliseconds);
        } catch (InterruptedException ignored) {
        }
    }

    /**
     * Run all threads and wait for them to finish without timeout
     */
    protected void startAndJoinAllThreads() {
        this.startAndJoinThreads(0);
    }


    protected void startThreads() {
        threadGroup.setTestResult(currentResult);
        Enumeration enum1 = threads.elements();
        while (enum1.hasMoreElements()) {
            ConcurrentTestThread each =
                (ConcurrentTestThread) enum1.nextElement();
            each.start();
            each.hasStarted = true;
        }
        Thread.yield();
    }



    protected void tearDown() throws Exception {
            this.interruptAllAliveThreads();
            threads = new Hashtable();
            checkpoints = new Vector();
            deadlockDetected = false;
            threadGroup = null;
            currentResult = null;
        }

    public synchronized void waitForCheckpoint(String checkpointName) {
        while (!this.checkpointReached(checkpointName)) {
            try {
                this.wait();
            } catch (InterruptedException ignored) {
            }
        }
    }


    public synchronized void waitUntilFinished(String threadName) {
        while (!this.hasThreadFinished(threadName)) {
            try {
                this.wait();
            } catch (InterruptedException ignored) {
            }
        }
    }
}
  

Я много пытался найти по этому поводу, но не нашел подходящего решения, так есть ли кто-нибудь, кто может мне помочь заменить this.stop() метод, который устарел.

Сообщение IDE: The method stop() from the type ThreadGroup is deprecated

Ответ №1:

Не существует единого метода, который заменяет stop() из Thread Group, а скорее дизайнерский подход

В документации oracle говорится

Многие варианты использования stop следует заменить кодом, который просто изменяет некоторую переменную, чтобы указать, что целевой поток должен прекратить выполнение. Целевой поток должен регулярно проверять эту переменную и возвращаться из своего метода run упорядоченным образом, если переменная указывает, что она должна прекратить выполнение

Просматривая примеры на Что я должен использовать вместо Thread.stop?

 private volatile Thread blinker;

public void stop() {
    blinker = null;
}

public void run() {
    Thread thisThread = Thread.currentThread();
    while (blinker == thisThread) {
        try {
            Thread.sleep(interval);
        } catch (InterruptedException e){
        }
        repaint();
    }
}
  

Во всем вашем потоке вам необходимо проверять потокобезопасную переменную (в примере выше ее индикатор)… когда вызывается stop, он присваивает потоку значение null, прерывая цикл while и возвращаясь из run… тем самым «останавливая» поток

Комментарии:

1. Можете ли вы еще раз просмотреть мой пост, я обновил его полными кодами, где я использую все эти темы, помощь будет оценена

2. Что-нибудь конкретное, на что нужно обратить внимание, ваши модульные тесты работают не так, как предполагалось?

3. Похоже, что они работают, пожалуйста, посмотрите на скриншот: ibb.co/HH5CC7k несмотря на то, что мне нужно удалить этот this.stop (), и я не знаю, помешает это рабочему процессу или нет?

Ответ №2:

Что ж, я перечислил немного документации о том, почему stop () устарел, и вот наиболее важная часть :

Этот метод по своей сути небезопасен. Остановка потока с помощью Thread.stop приводит к разблокировке всех мониторов, которые он заблокировал (как естественное следствие непроверенного исключения ThreadDeath, распространяющегося вверх по стеку). Если какой-либо из объектов, ранее защищенных этими мониторами, находился в несогласованном состоянии, поврежденные объекты становились видимыми для других потоков, что потенциально приводило к произвольному поведению. Многие варианты использования stop следует заменить кодом, который просто определяет некоторую переменную, чтобы указать, что целевой поток должен прекратить выполнение. Целевой поток должен регулярно проверять эту переменную и возвращаться из своего метода run упорядоченным образом, если переменная указывает, что она должна прекратить выполнение. Если целевой поток ожидает в течение длительных периодов (например, для переменной условия), для прерывания ожидания следует использовать метод interrupt.

Учитывая эти детали, я думаю, что более простого способа остановить все потоки, как это сделала stop(), не существует. Возможно, вам потребуется модифицировать потоки, чтобы у вас был способ остановить их (если это возможно для вас).

Комментарии:

1. Я попытался, добавив следующую переменную, кто-нибудь может сказать мне, будет ли это работать или нет? образец частного потока; общедоступный недействительный interruptThenStop() { sample.interrupt(); if (Thread.activeCount() > 0) { sample = null; } }