Как я могу заменить устаревший метод this.stop () в ThreadGroup - PullRequest
0 голосов
/ 08 марта 2019

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

this.stop ();

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

ThreadedTestGroup.java ::

    package utmj.threaded;

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

    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 = result;
    }


    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 currentResult;
    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 = result;
        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

Ответы [ 2 ]

1 голос
/ 08 марта 2019

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

Из документации оракула написано

Многие варианты использования 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, он устанавливает нуль в ноль, выходящий из цикла while и возвращающийся из run .. тем самым «останавливая» нить

0 голосов
/ 08 марта 2019

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

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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...