最新要闻

广告

手机

iphone11大小尺寸是多少?苹果iPhone11和iPhone13的区别是什么?

iphone11大小尺寸是多少?苹果iPhone11和iPhone13的区别是什么?

警方通报辅警执法直播中被撞飞:犯罪嫌疑人已投案

警方通报辅警执法直播中被撞飞:犯罪嫌疑人已投案

家电

Java并发(七)----线程sleep、yield、线程优先级

来源:博客园

1、sleep 与 yield

sleep

  1. 调用 sleep 会让当前线程从 Running进入 Timed Waiting状态(阻塞)

  2. 其它线程可以使用 interrupt 方法打断正在睡眠的线程,这时 sleep 方法会抛出 InterruptedException


    (资料图片)

  3. 睡眠结束后的线程未必会立刻得到执行

  4. 建议用 TimeUnit 的 sleep 代替 Thread 的 sleep 来获得更好的可读性(TimeUnit.SECONDS.sleep(1);)

调用sleep

public static void main(String[] args) {     Thread t1 = new Thread("t1") {       @Override       public void run() {         try {           Thread.sleep(2000);         } catch (InterruptedException e) {           e.printStackTrace();         }       }     };​     t1.start();     log.debug("t1 state: {}", t1.getState());​     try {       Thread.sleep(500);     } catch (InterruptedException e) {       e.printStackTrace();     }     log.debug("t1 state: {}", t1.getState());   }

输出

22:23:02.365 c.Test6 [main] - t1 state: RUNNABLE22:23:02.893 c.Test6 [main] - t1 state: TIMED_WAITING

调用interrupt

public static void main(String[] args) throws InterruptedException {     Thread t1 = new Thread("t1") {       @Override       public void run() {         log.debug("enter sleep...");         try {           Thread.sleep(2000);         } catch (InterruptedException e) {           log.debug("wake up...");           e.printStackTrace();         }       }     };     t1.start();​     Thread.sleep(1000);     log.debug("interrupt...");     t1.interrupt();   }

输出

22:26:48.155 c.Test7 [t1] - enter sleep...22:26:49.158 c.Test7 [main] - interrupt...22:26:49.158 c.Test7 [t1] - wake up...java.lang.InterruptedException: sleep interrupted    at java.lang.Thread.sleep(Native Method)    at cn.itcast.test.Test7$1.run(Test7.java:14)

yield

  1. 调用 yield 会让当前线程从 Running进入 Runnable就绪状态,然后调度执行其它线程,注意:如果没有其他线程的话,可能还是执行当前线程

  2. 具体的实现依赖于操作系统的任务调度器

2、sleep yield区别

共同点:

1.都是Thread类中的类方法

2.都会导致正在执行的线程释放CPU

区别:

1.线程进入的状态不同:sleep方法导致线程进入到阻塞状态,yield方法导致线程进入就绪状态

2.是否考虑线程优先级:sleep方法不会考虑线程优先级,当一个线程调用sleep方法释放CPU后,所有优先级级别的线程都有机会获得CPU。yield方法会考虑线程优先级。当一个线程调用sleep方法释放CPU后,与该线程具有同等优先级,或优先级比该线程高的线程有机会获得CPU

3.可移植性:sleep方法比yield方法具有更好的可移植性

4.是否抛出异常:sleep方法声明抛出InterruptedException,而yield方法没有声明任何异常

5.是否有参数:sleep方法在Thread类中有两种重载形式,sleep(long ms),sleep(long ms,int nanos)yield方法没有参数

3、线程优先级

  • 线程优先级会提示(hint)调度器优先调度该线程,但它仅仅是一个提示,调度器可以忽略它

  • 如果 cpu 比较忙,那么优先级高的线程会获得更多的时间片,但 cpu 闲时,优先级几乎没作用

所以不一定优先级设置高就一定能有限执行,具体执行依赖任务调度器。

Runnable task1 = () -> {  int count = 0;  for (;;) {    System.out.println("---->1 " + count++);   }};Runnable task2 = () -> {  int count = 0;  for (;;) {    // Thread.yield();    System.out.println("        ---->2 " + count++);   }};Thread t1 = new Thread(task1, "t1");Thread t2 = new Thread(task2, "t2");// t1.setPriority(Thread.MIN_PRIORITY);// t2.setPriority(Thread.MAX_PRIORITY);t1.start();t2.start();

这里读者可将注释去掉自行实践,即可体会yield与优先级的使用。

关键词: