多线程基础知识总结(四)

时间:2021-09-18 23:30:14

全文概要

本文主要介绍Thread类中 yield()方法和 sleep()方法的使用。包括以下内容:
  • 通过一个案例介绍yield()方法的使用;
  • 通过一个案例介绍sleep()方法的使用;
  • 通过以上案例比较yield()/sleep()/wait()三个方法的区别

yield()方法介绍

  • 代码案例
package com.tml.javaCore.thread;
/**
* <p>Thread中yield()方法介绍
* @author Administrator
*
*/
public class YieldDemo {
private Object obj = new Object();
public static void main(String[] args) {
YieldDemo demo = new YieldDemo();
new Thread(new Runnable() {
public void run() {
demo.print();
}
}, "thread_01").start();

new Thread(new Runnable() {
public void run() {
demo.print();
}
}, "thread_02").start();

}

private void print(){
synchronized (obj) {
for(int i=1;i<11;i++){
System.out.println(Thread.currentThread().getName() + ":is printing:" + i);
if(i % 5 ==0){
//让正在执行的线程让出CPU的执行权,从运行状态进入就绪状态
Thread.yield();
}
}
}
}

}
  • 输出结果
 thread_01:is printing:1
 thread_01:is printing:2
 thread_01:is printing:3
 thread_01:is printing:4
 thread_01:is printing:5
 thread_01:is printing:6
 thread_01:is printing:7
 thread_01:is printing:8
 thread_01:is printing:9
 thread_01:is printing:10
 thread_02:is printing:1
 thread_02:is printing:2
 thread_02:is printing:3
 thread_02:is printing:4
 thread_02:is printing:5
 thread_02:is printing:6
 thread_02:is printing:7
 thread_02:is printing:8
 thread_02:is printing:9
 thread_02:is printing:10

  • 结果分析
  1. 通过匿名内部类的方式创建两个线程,两个线程都是用的同一个对象锁;
  2. 当线程1先获取到对象锁后,循环5次后,执行Thread.yield(),会让线程1让出CPU的执行权,从运行状态进入就绪状态,和线程2一起竞争CPU资源,但是yield()方法不会释放对象锁,因此线程2获取不到CPU资源,线程1重新获取CPU资源后循环5次结束,线程1结束后释放对象锁;
  3. 线程2获取对象锁后,以此类推。

sleep()方法介绍

  • 代码案例
package com.tml.javaCore.thread;
/**
* <p>Thread中sleep()方法的介绍
* @author Administrator
*
*/
public class SleepDemo {
private Object obj = new Object();
public static void main(String[] args) {
SleepDemo demo = new SleepDemo();

new Thread(new Runnable() {
public void run() {
try {
demo.print();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}, "thread_01").start();

new Thread(new Runnable() {
public void run() {
try {
demo.print();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}, "thread_02").start();

}

private void print() throws InterruptedException{
synchronized (obj) {
for(int i=1;i<=10;i++){
System.out.println(Thread.currentThread().getName() + ":is printing:" + i);
if(i % 5 ==0){
//让正在执行的线程让出CPU的执行权,从运行状态进入阻塞状态
Thread.sleep(100);
}
}
}
}

}
  • 输出结果
 thread_01:is printing:1
 thread_01:is printing:2
 thread_01:is printing:3
 thread_01:is printing:4
 thread_01:is printing:5
 thread_01:is printing:6
 thread_01:is printing:7
 thread_01:is printing:8
 thread_01:is printing:9
 thread_01:is printing:10
 thread_02:is printing:1
 thread_02:is printing:2
 thread_02:is printing:3
 thread_02:is printing:4
 thread_02:is printing:5
 thread_02:is printing:6
 thread_02:is printing:7
 thread_02:is printing:8
 thread_02:is printing:9
 thread_02:is printing:10

  • 结果分析
  1. 通过匿名内部类的方式创建两个线程,启动线程;
  2. 线程1获取对象锁后,当循环5次后,执行Thread.sleep(100),会让线程让出CPU的资源,从运行状态进入阻塞状态,但sleep()方法一样不会释放对象锁,因此线程2不会获取到CPU的执行权,约100毫秒后,线程1从阻塞状态进入就绪状态,获取CPU资源后执行5次循环结束,释放对象锁;
  3. 线程2获取对象锁后,以此类推。

yield()/sleep()/wait()方法比较

  • yield()和wait()方法比较
  1. yield()定义在Thread中,而wait()定义在Object中,wait()必须依赖对象锁,而yield()不需要;
  2. yield()方法让线程从运行状态进入就绪状态,而wait()方法则是让线程从运行状态进入阻塞状态
  3. yield()方法不会释放对象锁,而wait()方法释放对象锁。
  • sleep()和wait()方法比较
  1. sleep()定义在Thread中,而wait()定义在Object中,wait()必须依赖对象锁,而sleep()不需要;
  2. sleep()方法让线程从运行状态进入阻塞状态,wait()方法也是让线程从运行状态进入阻塞状态
  3. sleep()方法不会释放对象锁,而wait()方法释放对象锁。
  • yield()和sleep()方法比较
  1. yield()定义在Thread中,sleep()同样也定义在Thread中;
  2. yield()方法让线程从运行状态进入就绪状态,而sleep()方法则是让线程从运行状态进入阻塞状态
  3. yield()和sleep()方法都不会释放对象锁。