您当前的位置: 首页 >  Java

小志的博客

暂无认证

  • 0浏览

    0关注

    1217博文

    0收益

  • 0浏览

    0点赞

    0打赏

    0留言

私信
关注
热门博文

Java并发多线程编程——自旋锁

小志的博客 发布时间:2021-04-16 22:04:09 ,浏览量:0

目录
    • 一、自旋锁的理解
    • 二、自旋锁的优点
    • 三、自旋锁的缺点
    • 四、自旋锁示例

一、自旋锁的理解
  • 当一个线程在获取锁的时候,如果锁已经被其它线程获取,那么该线程将循环等待,然后不断的判断锁是否能够被成功获取,直到获取到锁才会退出循环。
二、自旋锁的优点
  • 自旋锁不会使线程状态发生切换,一直处于用户态,即线程一直都是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){}判断产生自旋后,所有线程已结束才会在最后输出。否则,线程没执行完即输出了所有线程已结束
关注
打赏
1661269038
查看更多评论
立即登录/注册

微信扫码登录

0.0442s