Java多线程【线程阻塞工具类 LockSupport】用法详解!

本文介绍了Java中的LockSupport类,特别是park和unpark方法,它们用于线程的阻塞和唤醒,与wait和notify功能类似但不交叉,避免了死锁。还讨论了blocker参数的作用以及如何处理中断情况。

线程阻塞工具类 LockSupport

LockSupport常用的方法 park 和 unpark

public static void park(Object blocker)暂停当前线程
public static void park()无期限暂停当前线程
public static void parkNanos(Object blocker, long nanos)暂停当前线程,不过有超时时间的限制
public static void parkNanos(long nanos)暂停当前线程,不过有超时时间的限制
public static void parkUntil(long deadline)暂停当前线程,直到某个时间
public static void parkUntil(Object blocker, long deadline)暂停当前线程,直到某个时间
public static void unpark(Thread thread)用于解除给定线程的阻塞状态
public static Object getBlocker(Thread t)用于获取指定线程t在调用 park() 方法时被阻塞的对象。如果线程 t 是因为调用 park(Object blocker) 方法而被阻塞,那么 getBlocker(t) 方法将返回阻塞的对象。如果线程 t 没有因为调用 park() 方法而被阻塞,或者调用了 park() 方法但没有传入阻塞对象,那么 getBlocker(t) 方法将返回 null

参数解释

blocker参数可以传递任意对象,用于标识当前线程的阻塞原因,方便调试
nanos纳秒数,用于实现线程的定时等待
deadline要等待的绝对时间,以毫秒为单位。用于实现线程的定时等待,直到指定的时间点
thread参数thread是要解除阻塞的线程对象

示例

  • public static void park(Object blocker)

     当调用 LockSupport.park(Object blocker) 方法时,当前线程会被阻塞,暂停执行。
     
     解除阻塞方式:
     1. 其他线程调用了当前线程对应的 unpark(Thread thread) 方法,解除了阻塞
     2. 当前线程被中断
    

    park不需要获取某个对象的锁,
    因为中断的时候park不会抛出InterruptedException异常,
    所以需要在park之后自行判断中断状态,然后做额外的处理

package com.jdw.java8.thread;

import java.util.Random;
import java.util.concurrent.locks.LockSupport;

public class LockSupportExample {

	public static void main(String[] args) throws InterruptedException {
		Thread thread = new Thread(() -> {
			System.out.println("thread子线程开始");
			// 阻塞当前线程,并指定 blocker 参数
			LockSupport.park("thread子线程用于调试,此处被LockSupport.park阻塞!");
			if (Thread.currentThread().isInterrupted()) {
				System.out.println("thread子线程被中断了,异常退出,或者其它处理!");
				return;
			}
			System.out.println("thread子线程被唤醒");
		});

		thread.start();

		// 主线程等待一段时间后,唤醒子线程
		Thread.sleep(3000);
		// 获取指定线程t在调用 park() 方法时传入的被阻塞的对象
		Object blocker = LockSupport.getBlocker(thread);
		System.out.println(blocker); // 输出:thread子线程用于调试,此处被LockSupport.park阻塞!
		Thread.sleep(3000);

		// 1-10的随机整数
		int randomNumber = new Random().nextInt(10) + 1;
		if (randomNumber >= 5) {
			// 随机打断子线程
			thread.interrupt();
		}

		// 唤醒thread子线程
		LockSupport.unpark(thread);
	}
}

  • public static void unpark(Thread thread)

     unpark方法用于解除指定线程的阻塞状态,使其可以继续执行。
     如果指定线程当前处于阻塞状态,调用unpark方法会立即解除其阻塞状态;
     如果指定线程当前处于非阻塞状态,调用unpark方法不会产生任何效果。
    

小结

  • park和unpark可以实现类似wait和notify的功能,但是并不和wait和notify交叉,也就是说unpark不会对
    wait起作用,notify也不会对park起作用
  • park和unpark的使用不会出现死锁的情况
  • blocker的作用是看到阻塞对象的信息
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值