JAVA多线程---wait() & join()

Posted 丨核桃牛奶

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了JAVA多线程---wait() & join()相关的知识,希望对你有一定的参考价值。

题外话:

interrupt()方法  并不能中断一个正常运行的线程!!!

class myThread extends Thread{
    @Override
    public void run(){
        for (int i = 0; i < 1000; i++) {
            System.out.println(i);
        }
    }
}
public class waitTest {

    public static void main(String[] args) throws Exception{
        Thread t =new myThread();
        t.start();
        t.interrupt();
        System.out.println("mark");
    }

}

 

输出:

mark

......

i=999

public class waitTest {

    public static void main(String[] args) throws Exception{

        Thread.currentThread().interrupt();
        System.out.println("是否停止1?" + Thread.interrupted());
        System.out.println("是否停止2?" + Thread.interrupted());
        System.out.println("end!");
    }

}

此时的输出为

是否停止1?true
是否停止2?false
end!

interrupt虽然不能中断一个正常执行的线程,但是会将目标线程的中断状态置为true   而interrupted用于测试当前线程的中断状态,执行后将状态表示置为false

而且interrupt只能中断一个正处于‘‘异常’’状态的线程 

 

class myThread extends Thread{
    @Override
    public void run(){
        for (int i = 0; i < 1000; i++) {

            System.out.println(i);
            if(i==800){
                try{
                    Thread.sleep(1000);
                }catch (Exception e){
                    System.out.println(i+"$$");
                    e.printStackTrace();
                    System.out.println(i+"^^");

                }
            }
        }
    }
}
public class waitTest {

    public static void main(String[] args) throws Exception{

        Thread t =new myThread();
        t.start();
        t.interrupt();
        System.out.println("end");
    }

}

 

输出为:

end    //说明interrupt已经发送 

0

...

800
800$$   //说明确实是在i=800 处抛出异常  不过异常信息打印的稍有延迟???
800^^
801

912

java.lang.InterruptedException: sleep interrupted
913
914
at java.lang.Thread.sleep(Native Method)
915
at luyudepackage.myThread.run(waitTest.java:22)

...

999

说明interrupt方法可以提前发送 将目标线程中断状态置为true 当目标线程进入sleep状态时 抛出异常


 

join()方法 

具体用法http://www.cnblogs.com/luyu1993/p/7017927.html

这里看下它的源码

public final synchronized void join(long millis) 
    throws InterruptedException {
    long base = System.currentTimeMillis();
    long now = 0;

    if (millis < 0) {
            throw new IllegalArgumentException("timeout value is negative");
    }

    if (millis == 0) {
        while (isAlive()) {
        wait(0);
        }
    } else {
        while (isAlive()) {
        long delay = millis - now;
        if (delay <= 0) {
            break;
        }
        wait(delay);
        now = System.currentTimeMillis() - base;
        }
    }
    }

  

join()内部调用的是wait()  注意 在调用wait()之前,线程必须获得该对象的锁,因此只能在同步方法/同步代码块中调用wait()方法。可以看见join()方法是synchronized的 所以没问题

看下面这段代码

 1 class myThread extends Thread{
 2     @Override
 3     public void run(){
 4         for (int i = 0; i < 1000; i++) {
 5             System.out.println(i);
 6         }
 7     }
 8 }
 9 public class waitTest {
10 
11     public static void main(String[] args) throws Exception{
12         Thread t =new myThread();
13         t.start();
14         Thread.currentThread().wait();
15         System.out.println("mark");
16     }
17 
18 }

此时程序会报错  不在同步方法/同步代码块 中调用wait()方法的错误!!!

 多次start同一个线程

 

以上是关于JAVA多线程---wait() & join()的主要内容,如果未能解决你的问题,请参考以下文章

java里多线程的wait问题

java多线程&并发面试108问(中)

java多线程&并发面试108问(中)

JUC并发编程 -- 回顾多线程(线程的六种状态 & wait / sleep 的区别)

java并发 day02 临界区和竞态条件synchronized线程安全 对象头 Monitor管程 wait notifypark&unpark ReentrantLock

java并发 day02 临界区和竞态条件synchronized线程安全 对象头 Monitor管程 wait notifypark&unpark ReentrantLock