简体   繁体   English

线程完成后运行线程的run()方法

[英]Running a thread's run() method after a thread has completed

I am trying to understand the state of a Thread object after the thread has completed. 我试图在线程完成后了解Thread对象的状态。 I read in a book that once a thread has completed its run() method, the thread object will still be a valid object on the head and can still be used as an instance object and you can still call methods on it. 我在一本书中读到,一旦线程完成其run()方法,该线程对象在头部仍将是有效对象,并且仍可用作实例对象,并且您仍可以在其上调用方法。 I decided to try this with the following example: 我决定尝试以下示例:

class DieThread implements Runnable{

    int y = 0;

    public void run(){
        for(int x=0; x<100; x++){
            System.out.println("             " + Thread.currentThread().getName());
            System.out.println("y is " + y);
            y++;
            System.out.println("y is " + y);
        }
    }   
}

class ZiggyTest2{
    public static void main(String[] args){     

        DieThread d = new DieThread();

        Thread a = new Thread(d);
        Thread b = new Thread(d);
        Thread c = new Thread(d);

        a.start();
        b.start();
        c.start();

        try{
            a.join();
            b.join();
            c.join();
        }catch(Exception e){
            System.out.println(e);
        }

        System.out.println("Running C's Run");
        c.run();        
    }
}

main() waits for the other 3 threads to complete by using join(). main()使用join()等待其他3个线程完成。 It then call c's run() method but for some reason it is not printing out anything from the run() method. 然后,它调用c的run()方法,但是由于某种原因,它没有从run()方法中打印出任何内容。 Here is the last few lines of the output after i run the above program. 这是运行上述程序后输出的最后几行。

y is 287
y is 287
y is 288
y is 289
             Thread-1
             Thread-0
y is 289
y is 289
y is 290
y is 291
             Thread-1
             Thread-0
y is 291
y is 291
y is 292
y is 293
             Thread-1
             Thread-0
y is 293
y is 293
y is 294
y is 295
             Thread-0
y is 295
y is 296
             Thread-0
y is 296
y is 297
             Thread-0
y is 297
y is 298
             Thread-0
y is 298
y is 299
             Thread-0
y is 299
y is 300
Running C's Run

Even though the thread has completed, i was expecting the value of y to be 400 because of the c.run() call. 即使线程已完成,由于c.run()调用,我仍期望y的值为400。

Any ideas? 有任何想法吗?

Thanks 谢谢

If you extend the Thread class, it'd work. 如果扩展Thread类,它将起作用。 Now it checks the Runnable target which is null after Thread.exit() 现在,它检查Thread.exit()之后为nullRunnable目标。

Synchronize access to the state of the object DieThread 同步访问对象DieThread的状态

synchronized(this) {
    System.out.println("             " + Thread.currentThread().getName());
    System.out.println("y is " + y);
    y++;
    System.out.println("y is " + y);
}

The reason for what you are observing is buried in the implementation of the Thread class. 您正在观察的原因埋藏在Thread类的实现中。

When you call c.run() you are calling the run method on the thread object. 当您调用c.run()您正在调用线程对象上的run方法。 This is specified as calling the run method of the target object (ie the runnable supplied in the Thread constructor) if it is not null . 如果它不为null则指定为调用target对象的run方法(即Thread构造函数中提供的runnable)。 If target is null then the Thread.run() method does nothing. 如果targetnullThread.run()方法不执行任何操作。

OK, so you supplied a non-null target . 好的,所以您提供了一个非null的target

In fact, when a Thread finishes, the Thread.exit() method is called to clean up. 实际上,当Thread完成时,将Thread.exit()方法进行清理。 And one of the things that the cleanup does is to assign null to target . 清除操作之一就是将null分配给target (The code has a comment about needing to aggressively clear references, and a bug id. Unfortunately, the corresponding bug report is missing, so it is not possible to know the real reason(s) that they do this.) (代码中有关于需要积极清除引用的注释以及错误ID。不幸的是,缺少相应的错误报告,因此无法知道他们这样做的真正原因。)

Anyway, the bottom line is that you can't rerun the target object's run() method by calling Thread.run() . 无论如何,最重要的是您无法通过调用Thread.run()重新运行目标对象的run()方法。 But you can call the target object's run() method directly ... if you have the target reference. 但是,如果您有目标引用,则可以直接调用目标对象的run()方法。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM