0
点赞
收藏
分享

微信扫一扫

Java 多线程中wait、notify、nptifyAll、yield、join、sleep的使用方法及区别

在Java多线程编程中,会涉及到wait、notify、nptifyAll、yield、join、sleep线程间交互的方法,这些比较晦涩难懂,现在全面介绍下这些方法的使用方式。

1. 总览

这些方法可大致分为两类,一类是继承自Object的方法,全部为native实现,一类是Thread的方法,也都是依托native实现的。

1) 继承自Object
  • notify()
  • notifyAll()
  • wait()
  • wait(long timeout)
  • wait(long timeout, int nanos)

2) Thread的方法
  • static yield()
  • static sleep(long millis)
  • static sleep(long millis, int nanos)
  • join(long millis)
  • join(long millis, int nanos)
  • join()


2. 线程状态转换

2.使用说明

1) wait/wait(time) 与 notify/notifyAll
2) sleep
3) yield
  • 代码样例
import java.time.LocalTime;

public class YieldTest {

    public static void main(String[] args) {
        Thread thread = new Thread(new MyThread());
        thread.start();

        Thread thread2 = new Thread(new MyThread());
        thread2.start();
    }

    public static class MyThread implements Runnable{

        @Override
        public void run() {
            for (int i = 0; i < 10; i++) {
                System.out.println(Thread.currentThread().getName() + " " + i + " " + LocalTime.now());
                Thread.yield();
                System.out.println(Thread.currentThread().getName() + " " + i + " yield " + LocalTime.now());
            }
        }
    }
}
4) join/join(time)

如下代码表示主线程调用了thread的join方法,形成阻塞,thread睡了2秒后,主线程继续执行。

  • 代码样例
import java.time.LocalTime;

public class JoinTest {

    public static void main(String[] args) throws InterruptedException {
        Thread thread = new Thread(new MyThread());
        thread.start();

        System.out.println("Main join wait " + LocalTime.now());
        thread.join();
        System.out.println("Main end " + LocalTime.now());
    }

    public static class MyThread implements Runnable{

        @Override
        public void run() {
            try {
                Thread.sleep(2000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}
  • 输出
Main join wait 00:35:33.265
Main end 00:35:35.199
  • 源码解读
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) {
        //无限等待至该线程可用死亡(!isAlive())
        //isAlive与wait都是native方法
        while (isAlive()) {
            wait(0); // 复用Object的wait方法
        }
    } else {
        while (isAlive()) {
            long delay = millis - now;
            if (delay <= 0) {
                break;
            }
            wait(delay);
            now = System.currentTimeMillis() - base;
        }
    }
}

参考

  1. Java线程源码解析之yield和sleep
举报

相关推荐

0 条评论