我已按顺序启动线程,但我不知道如何以相反的顺序停止它们。 例如: 它们是这样开始的:A-> B-> C-> D 并且我希望它们停止:D-> C-> B-> A 我根本不知道如何停止线程,甚至不按此顺序停止线程。 我感谢任何帮助或建议。
import java.util.*;
class Service extends Thread
{
private RobotController controller;
private String robotID;
private byte[] lock;
public Service(RobotController cntrl, String id)
{
controller = cntrl;
robotID = id;
}
public byte[] getLock() { return lock;}
public void run()
{
lock = new byte[0];
synchronized(lock)
{
byte[] data;
while ((data = controller.getData()) == null)
{
try {
lock.wait();
} catch (InterruptedException ie) {}
}
System.out.println("Robot " + robotID + " Working");
}
}
}
class RobotController
{
private byte[] robotData;
private Vector threadList = new Vector();
private Service thread_A;
private Service thread_B;
private Service thread_C;
private Service thread_D;
private volatile boolean done;
public void setup(){
thread_A = new Service(this, "A");
thread_B = new Service(this, "B");
thread_C = new Service(this, "C");
thread_D = new Service(this, "D");
threadList.addElement(thread_A);
threadList.addElement(thread_B);
threadList.addElement(thread_C);
threadList.addElement(thread_D);
thread_A.start();
thread_B.start();
thread_C.start();
thread_D.start();
start();
stop();
}
public void start()
{
System.out.println("Thread starts");
{
for (int i=0; i <= 3; i++)
{
try {
Thread.sleep(500);
}catch (InterruptedException ie){}
putData(new byte[10]);
Service rbot = (Service)threadList.elementAt(i);
byte[] robotLock = rbot.getLock();
synchronized(robotLock) {
robotLock.notify();
}
}
}
}
public void stop()
{
{
}
}
public synchronized byte[] getData()
{
if (robotData != null)
{
byte[] d = new byte[robotData.length];
System.arraycopy(robotData, 0, d, 0, robotData.length);
robotData = null;
return d;
}
return null;
}
public void putData(byte[] d) { robotData = d;}
public static void main(String args[])
{
RobotController controller = new RobotController();
controller.setup();
}
}
答案 0 :(得分:2)
如果我想明确地终止它们,我通常会在我的线程中包含类似cancel()
方法的内容。
class Service extends Thread {
private volatile boolean cancel = false;
public void cancel() {
cancel = true;
}
public void run() {
...
while (!cancel && (data = controller.getData()) == null) {
...
}
}
}
按照mre的建议将线程保持在堆栈中,然后弹出堆栈并在每个线程上调用cancel
然后interrupt
。
答案 1 :(得分:2)
我按顺序启动了线程,但我不知道如何以相反的顺序停止它们。
这很难做到。有一些方法可以通过设置volatile
关闭布尔值或中断它们来停止线程,但是这些机制都不能保证立即停止线程。
您构建它们时当然可以保留List<Thread>
,然后拨打Collections.reverse(threadList)
,然后依次致电thread.interrupt()
。如果必须按顺序完成它们,那么你应该打断它们,然后加入它们。类似的东西:
Collections.reverse(threadList);
for (Thread thread : threadList) {
thread.interrupt();
thread.join();
}
然后每个线程应该做类似的事情:
while (!Thread.currentThread().isInterrupted()) {
...
}
请注意,如果您正在运行Thread.sleep(...)
或其他抛出InterruptedException
的方法,则需要重新启用中断标志:
try {
Thread.sleep(...);
} catch (InterruptedException e) {
// by convention if InterruptedException thrown, interrupt flag is cleared
Thread.currentThread().interrupt();
...
}
答案 2 :(得分:1)
让每个线程保持对下一个要启动的线程的引用。然后每个线程可以定期检查线程是否仍然存活。如果不是,那个线程应该终止。当它发生时,前一个线程会注意到并终止,依此类推。
abstract class ChainThread extends Thread {
private final Thread next;
ChainThread(Thread next) { this.next = next; }
@Override
public final void run() {
next.start();
while (!Thread.currentThread().isInterrupted() && next.isAlive()) {
do();
}
}
abstract void do();
}
答案 3 :(得分:0)
如果我正确读取Service
代码,它会一直等到有数据要执行,然后结束。因此,您实际上不需要明确的stop
或cancel
类型信号,线程将在它们工作后自行终止。
要强制执行关机排序,您可以让每个Service
知道之前的Service
,然后拨打previousService.join()
。假设没有抛出InterruptedExceptions
,它们将在看到控制器有数据后按顺序关闭。
以这种方式创建服务:
Service serviceA = new Service(controller, "A", null);
Service serviceB = new Service(controller, "B", serviceA);
Service serviceC = new Service(controller, "C", serviceB);
Service serviceD = new Service(controller, "D", serviceC);
并且编辑实现以仅在依赖Services
完成后才退出:
private final RobotController controller;
private final String robotID;
private byte[] lock;
private final Service dependentService;
public Service(RobotController cntrl, String id, Service dependentService) {
controller = cntrl;
robotID = id;
this.dependentService = dependentService;
}
public byte[] getLock() {
return lock;
}
@Override
public void run() {
lock = new byte[0];
synchronized (lock) {
byte[] data;
while ((data = controller.getData()) == null) {
try {
lock.wait();
}
catch (InterruptedException ie) {
}
}
System.out.println("Robot " + robotID + " Working");
}
if (dependentService != null) {
try {
dependentService.join();
}
catch (InterruptedException e) {
this.interrupt();
}
}
}