我如何替换ThreadGroup中已弃用的方法this.stop()

时间:2019-03-08 20:41:36

标签: java multithreading deprecated threadgroup

我正在研究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 个答案:

答案 0 :(得分:1)

没有一种方法可以替代线程组中的stop(),而是一种设计方法

从oracle文档中说

  

stop的许多用法应该由简单修改的​​代码代替   一些变量指示目标线程应停止运行。   目标线程应定期检查此变量,然后返回   如果变量指示从其run方法按有序方式   要停止运行

查看What should I use instead of 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循环并从运行返回。 ,从而“停止”线程

答案 1 :(得分:0)

好吧,我用红色的文档说明了为什么不建议使用stop(),这是最相关的部分:

  

此方法本质上是不安全的。使用Thread.stop停止线程会导致它解锁所有已锁定的监视器(由于未经检查的ThreadDeath异常会在堆栈中传播,这是自然的结果)。如果先前由这些监视器保护的任何对象处于不一致状态,则损坏的对象将对其他线程可见,从而可能导致任意行为。 stop的许多用法应替换为简单地m>修改一些变量以指示目标线程应停止运行的代码。目标线程应定期检查此变量,如果该变量指示要停止运行,则应按有序方式从其运行方法返回。如果目标线程等待很长时间(例如,在条件变量上),则应使用interrupt方法来中断等待。

有了这些细节,我认为没有像stop()那样停止所有线程的简单方法了。您可能需要修改线程,以便有办法停止它们(如果可能的话)。