java - volatile Thread 不等于 Thread.currentThread

标签 java

我正在学习 Java 中的线程,我有以下程序。 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(),在该方法中您将自己的 boolean 变量(例如 stopMe)设置为 false,并在线程的方法 run() 中定期测试它的值。如果应用程序代码将 stopMe 的值设置为 true,则只需退出方法 run() 中的代码执行。在 list 20-10 中,方法 run 中的循环检查变量 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());
        }

     }
 }

最佳答案

threadA 字段由主线程初始化,在 ThreadA 对象成为当前线程之前,因此它的值被设置为主线程。当循环运行时,ThreadA 是当前线程,因此不会发生迭代。您在重新启动 Eclipse 之前获得的奇怪输出可能是由于 Eclipse 运行了您的代码的先前版本。

关于java - volatile Thread 不等于 Thread.currentThread,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17507941/

相关文章:

java - 动态分配 id 给 div

Java - 匹配字符串中的特定URL

java - Guava MapMaker().weakKeys().makeMap() 与 WeakHashMap

java - 改造错误 com.google.gson.JsonSyntaxException : java. lang.IllegalStateException:应为 BEGIN_OBJECT 但在第 1 行第 1 列路径 $

java - 如何从iso获取国家电话前缀

java - 从 Eclipse 中运行的 JUnit 测试检测 Eclipse 版本

java - 尝试从列表构造 HashSet<Integer> 时参数不匹配 - 为什么?

java - 在 Java 集合排序中使用 Comparator 接口(interface)比较方法返回值 -1, 0, 1 到底意味着什么?

java - 列表对象的继承和转换

java - 在 Java 中是否有 'this' 的静态版本