目录
一、自旋锁的理解
- 一、自旋锁的理解
- 二、自旋锁的优点
- 三、自旋锁的缺点
- 四、自旋锁示例
- 当一个线程在获取锁的时候,如果锁已经被其它线程获取,那么该线程将循环等待,然后不断的判断锁是否能够被成功获取,直到获取到锁才会退出循环。
- 自旋锁不会使线程状态发生切换,一直处于用户态,即线程一直都是active的。
- 不会使线程进入阻塞状态,减少了不必要的上下文切换,执行速度快。
- 如果某个线程持有锁的时间过长,就会导致其它等待获取锁的线程进入循环等待,消耗CPU。使用不当会造成CPU使用率极高。
- 自旋锁如果不是公平的(即无法满足等待时间最长的线程优先获取锁)。不公平的锁就会存在“线程饥饿”问题。
示例场景:多个线程执行结束后,输出“所有线程已结束”。
1、代码
package com.xz.thread.t5;
import java.util.Random;
/**
* @description: 自旋锁示例
* @author: xz
*/
public class Demo2 {
public static void main(String[] args) {
//第一个线程
new Thread(new Runnable() {
@Override
public void run() {
System.out.println(Thread.currentThread().getName()+"线程执行中......");
try {
Thread.sleep(new Random().nextInt(2000));
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName()+"线程执行完毕......");
}
}).start();
//第二个线程
new Thread(new Runnable() {
@Override
public void run() {
System.out.println(Thread.currentThread().getName()+"线程执行中......");
try {
Thread.sleep(new Random().nextInt(2000));
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName()+"线程执行完毕......");
}
}).start();
//第三个线程
new Thread(new Runnable() {
@Override
public void run() {
System.out.println(Thread.currentThread().getName()+"线程执行中......");
try {
Thread.sleep(new Random().nextInt(2000));
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName()+"线程执行完毕......");
}
}).start();
//第四个线程
new Thread(new Runnable() {
@Override
public void run() {
System.out.println(Thread.currentThread().getName()+"线程执行中......");
try {
Thread.sleep(new Random().nextInt(2000));
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName()+"线程执行完毕......");
}
}).start();
/**
* activeCount() 获取所有活动线程的数量
* Thread.activeCount() == 1 说明线程的活动的数量只有主线程一个
*/
while(Thread.activeCount() != 1){//说明线程没有执行完毕
//自旋
}
System.out.println("所有线程已结束==========");
}
}
2、输出结果 3、步骤1中的代码去掉while(Thread.activeCount() != 1){},输出如下:
4、结论
- 由第2步截图可知,当添加while(Thread.activeCount() != 1){}判断产生自旋后,所有线程已结束才会在最后输出。否则,线程没执行完即输出了所有线程已结束