您当前的位置: 首页 >  ar

Dongguo丶

暂无认证

  • 1浏览

    0关注

    472博文

    0收益

  • 0浏览

    0点赞

    0打赏

    0留言

私信
关注
热门博文

线程间通信LockSupport的parkunpark

Dongguo丶 发布时间:2021-09-10 15:22:55 ,浏览量:1

LockSupport是jdk自带的线程阻塞、唤醒工具类

此工具类属于juc包的一部分,所在包路径:java.util.concurrent.locks.LockSupport。

clipboard

LockSupport类使用了一种名为Permit(许可)的概念来做到阻塞和唤醒线程的功能,可以把许可看成是一种(0,1)信号量(Semaphore),但与 Semaphore 不同的是,许可的累加上限是1。

初始时,permit为0,当调用unpark()方法时,线程的permit加1,当调用park()方法时,如果permit为0,则调用线程进入阻塞状态。

使用LockSupport实现线程的阻塞和唤醒

package com.dongguo.sync;

import java.util.concurrent.locks.LockSupport;

/**
 * @author Dongguo
 * @date 2021/8/24 0024-17:15
 * @description: LockSupport示例
 */
public class ThreadDemo5 {
    static boolean flag = true;
    static Thread threadA;
    public static void main(String[] args) {
        DemoClass demoClass = new DemoClass();
         threadA = new Thread(() -> {
            demoClass.increment();
        }, "ThreadA");
        threadA.start();
        new Thread(() -> {
            demoClass.decrement();
        }, "ThreadB").start();
    }

    static class DemoClass {
        private int number = 0;

        //加一
        public  void increment() {
            try {
                while (true) {
                    while (number != 0) {
                        LockSupport.park();
                    }
                    if (flag) {
                        number++;
                        System.out.println(Thread.currentThread().getName() + "+1值为:" + number);
                        flag = false;
                    }
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }

        //减一
        public  void decrement() {
            try {
                while (true) {


                    if (!flag) {
                        number--;
                        System.out.println(Thread.currentThread().getName() + "-1值为:" + number);
                        flag = true;
                    }
                    LockSupport.unpark(threadA);
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }
}

image-20210910145051029

通过LockSupport的这两个方法,可以很方便的阻塞和唤醒线程。但是LockSupport的使用过程中还需要注意以下几点:

  1. park方法的调用一般要方法一个循环判断体里面。
  2. park方法是会响应中断的,但是不会抛出异常。(也就是说如果当前调用线程被中断,则会立即返回但不会抛出中断异常)
  3. park的重载方法park(Object blocker),会传入一个blocker对象,所谓Blocker对象,其实就是当前线程调用时所在调用对象(如上述示例中的FIFOMutex对象)。该对象一般供监视、诊断工具确定线程受阻塞的原因时使用。
关注
打赏
1638062488
查看更多评论
立即登录/注册

微信扫码登录

0.0367s