#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; } }