我正在学习Java中的Threads,我有以下程序。 ThreadA中的while threadA条件检查似乎并不像我期望的那样频繁。我在控制台窗口中看到的唯一println语句包含大于100的i变量。好像它等待并慢慢打印到控制台。我想这会在一秒左右完成。我显然在这里误解了一些东西,关于为什么ThreadTester不打印100次的任何想法?
public class ThreadTester {
public static void main(String[] args) {
ThreadA threadA = new ThreadA();
threadA.start();
}
}
public class ThreadA extends Thread{
private volatile Thread threadA = Thread.currentThread();
public void run() {
while(threadA == Thread.currentThread()){
for(int i=0; i<100; i++){
System.out.println("ThreadA " + i);
}
}
}
public void stopThread(){
threadA = null;
}
}
示例输出:
ThreadA 120
ThreadA 121
ThreadA 122
ThreadA 123
ThreadA 124
ThreadA 125
ThreadA 126
ThreadA 127
ThreadA 128
ThreadA 129
ThreadA 130
ThreadA 131
ThreadA 132
ThreadA 133
ThreadA 134
ThreadA 135
ThreadA 136
如何杀死一条线
Thread类有一个方法stop(),它应该知道如何杀死当前线程。但它在很多年前就被弃用了,因为它可能会导致程序中的某些对象因不正确的锁定和解锁对象实例而导致不一致状态。
杀死线程有不同的方法。其中一个涉及在线程上创建自己的方法,比如说stopMe(),在其中将自己的布尔变量(例如stopMe)设置为false并在线程的方法run()中定期测试其值。如果应用程序代码将stopMe的值设置为true,则只需退出方法run()中的代码执行。在代码清单20-10中,方法运行中的循环检查变量stopMe的值,该变量使用对当前Thread对象的引用进行初始化。一旦更改(在这种情况下设置为null),处理将完成。
变量stopMe已使用volatile关键字声明,该关键字警告Java编译器另一个线程可以修改它,并且该变量不应缓存在寄存器中,以便所有线程必须始终看到其新值。
预订示例代码如何构建线程,以便在需要时可以将其终止:
class KillTheThread{
public static void main(String args[]){
Portfolio4 p = new Portfolio4("Portfolio data");
p.start();
// Some other code goes here,
// and now it's time to kill the thread
p.stopMe();
}
}
class Portfolio4 extends Thread{
private volatile Thread stopMe = Thread.currentThread();
public void stopMe() {
stopMe = null;
}
public void run() {
while (stopMe == Thread.currentThread()) {
try{
//Do some portfolio processing here
}catch(InterruptedException e ){
System.out.println(Thread.currentThread().getName()
+ e.toString());
}
}
}
答案 0 :(得分:3)
threadA
字段由主线程初始化,在ThreadA
对象成为当前线程之前,因此其值被设置为主线程。当循环运行时,ThreadA
是当前线程,因此不会发生迭代。在重新启动Eclipse之前获得的奇怪输出可能是由于Eclipse运行了以前版本的代码。
答案 1 :(得分:1)
1.仅当ThreadA是主线程时,这将起作用。
2.
有一种非常简单的stopMe()方式。
private volatile boolean stopped = false;
public void stopMe() {
stopped = true;
}
public void run() {
while (!stopped) {
// ...
}
}
3.关于“如何杀死一个线程”。您可以使用Thread.interrupt()
实际上,FutureTask.cancel()
使用Thread.interrupt()
来停止工作线程。
但是,调用interrupt()实际上只是向线程发送信号。线程必须做一些额外的工作来响应信号。它不会自行停止。
最终您需要检查InterruptedException
和Thread.isInterrupted()
,这与stopMe()
基本相同。