【java并发】基础(3)--sleep、join、yield

来源:互联网 发布:java内存模型面试回答 编辑:程序博客网 时间:2024/06/05 08:54

一、sleep()

1.1 sleep()简介

  sleep() 的作用是让当前线程休眠,即当前线程会从“运行状态”进入到“休眠(阻塞)状态”。在线程重新被唤醒时,它会由“阻塞状态”变成“就绪状态",从而等待cpu的调度执行。
  sleep()会指定休眠时间,线程休眠的时间会大于/等于该休眠时间。

1.2 sleep()的使用

  Thread.sleep(100);

1.3 sleep()与wait()区别

  wait 和 sleep都会造成某种形式的暂停。wait()用于线程间通信,作用是让当前线程由“运行状态”进入”等待(阻塞)状态”;而sleep()的作用是让当前线程由“运行状态”进入到“休眠(阻塞)状态”。
  wait()会释放对象的同步锁;而sleep()则不会释放锁,仅仅释放CPU资源或者让当前线程停止执行一段时间。

二、join()

2.1 join()简介

  如果一个线程A执行了thread.join()语句,其含义是:当前线程A等待thread线程终止之后才从thread.join()返回。
  线程Thread除了提供join()方法之外,还提供了join(long millis)和join(long millis,int nanos)两个具备超时特性的方法。这两个超时方法表示,如果线程thread在给定的超时时间里没有终止,那么将会从该超时方法中返回。

2.2 join()示例

有三个线程T1,T2,T3,怎么确保它们按顺序执行?

/** * 有三个线程T1,T2,T3,怎么确保它们按顺序执行? * join() * @author lc 2017/5/3 */public class TestJoin {    public static void main(String[] args) {                final Thread t1 = new Thread(new Runnable() {            @Override            public void run() {                System.out.println(Thread.currentThread().getName());            }        },"T1");        final Thread t2 = new Thread(new Runnable() {            @Override            public void run() {                try {                    t1.join();                } catch (InterruptedException e) {                    e.printStackTrace();                }                System.out.println(Thread.currentThread().getName());            }        },"T2");        Thread t3 = new Thread(new Runnable() {            @Override            public void run() {                try {                    t2.join();                } catch (InterruptedException e) {                    e.printStackTrace();                }                System.out.println(Thread.currentThread().getName());            }        },"T3");        t3.start();        t2.start();//      try {//          Thread.sleep(300);//      } catch (InterruptedException e) {//          e.printStackTrace();//      }        t1.start();    }}

输出结果:T1
     T2
     T3

2.3 join()源码

1.join()方法

public final void join() throws InterruptedException {        join(0); //实际是调用join(long millis)}

2.join(long millis)方法

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");        }        //join()方法。join(0)        if (millis == 0) {            while (isAlive()) {//判断本线程是否为活动状态(活动状态指线程已经启动且尚未终止)                wait(0); //等待            }        } else {            while (isAlive()) {                long delay = millis - now;                if (delay <= 0) {                    break;                }                wait(delay);                now = System.currentTimeMillis() - base;            }        }    }

三、yield()

3.1 yield()简介

  yield()的作用是让步。它能让当前线程由“运行状态”进入到“就绪状态”,从而让其它具有相同优先级的等待线程获取执行权。但是,并不能保证在当前线程调用yield()之后,其它具有相同优先级的线程就一定能获得执行权,也有可能是当前线程又进入到“运行状态”继续运行!

3.2 yield()的使用

  Thread.yield();

3.3 为什么Thread类的sleep()和yield()方法是静态的?

  Thread类的sleep()和yield()方法将在当前正在执行的线程上运行,其他处于等待状态的线程调用这些方法是没有意义的。将这些方法设计成静态的,可以在当前正在执行的线程中工作,并避免程序员错误的认为可以在其他非运行线程调用这些方法。

参考资料

Java多线程系列–“基础篇”07之 线程休眠
Java多线程系列–“基础篇”08之 join()
浅析 Java Thread.join()
Java多线程系列–“基础篇”06之 线程让步
《java并发编程的艺术》

0 0
原创粉丝点击