Java 多线程高并发 3.8 — LockSupport 简单使用

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/ocp114/article/details/82851890

先讲讲主要的 api

名称 描述
park() 相当于 suspend() 使线程挂起
unpark(Thread thread) 相当于 thread.resume() 唤醒线程
park(Object blocker) 功能和 park() 一样,但是 blocker 可以当作参数在不同线间传递
getBlocker(Thread t) 可以获取到线程 t 调用 park(Object blocker) 时传进去的 blocker
parkNanos(long nanos) nanos 为纳秒,1毫秒(ms) = 1000000纳秒(ns),让当前线程最长沉睡 nanos 时间长度(如果有其他线程在这时间内唤醒的话,会立刻运行)
parkNanos(Object blocker, long nanos) 这个就不说了,用大腿想想
parkUntil(long deadline) deadline 为未来的一个时间时间戳,单位是毫秒,方法是作用是让当前线程沉睡至 deadline 的时间后重新唤醒
parkUntil(Object blocker, long deadline) 哈~这个也不说

一些特性:

  1. 全部静态方法,方便调用
  2. 底层通过 Unsafe 来实现,可以说是有借助系统层级还有硬件相关的放来来实现锁的控制了
  3. 被阻塞的线程可以被中断,不抛异常,可以通过 isInterrupted() 查询是否被中断,被中断的锁所在的线程会立刻往下执行,有点像调用了 unpark(Thread thread) 方法
  4. park() 和 unpark(Thread thread) 调用的次序可以掉乱,但是,如果在 park() 前调用了 unpark(Thread thread) 那么这个 park() 方法基本上就是废了

基本使用:

public class TestLockSupport {
	
	private static SimpleDateFormat formatter = new SimpleDateFormat("HH:mm:ss:SSS");
	
	static class TestThread implements Runnable {
		@Override
		public void run() {
			System.out.println("1) " + formatter.format(new Date()) + " : " + Thread.currentThread().getName() + " 进来了");
			System.out.println("2) " + formatter.format(new Date()) + " : " + "执行普通  park() 让线程挂起 ");
			LockSupport.park();
			
			System.out.println("4) " + formatter.format(new Date()) + " : " + "执行 park(blocker) 为主线程传递参数 ");
			String blocker = "我是 blocker";
			LockSupport.park(blocker);
			
			System.out.println("7) " + formatter.format(new Date()) + " : " + "执行 parkNanos(nanos) 让线程沉睡 2 秒 ");
			LockSupport.parkNanos(2000000000);

			String blocker1 = "我是 blocker1";
			System.out.println("8) " + formatter.format(new Date()) + " : " + "执行 parkNanos(blocker, nanos) 让线程沉睡 2 秒,并为主线程传递参数");
			LockSupport.parkNanos(blocker1, 2000000000);
			
			System.out.println("10) " + formatter.format(new Date()) + " : " + "执行 parkUntil(deadline) 让线程沉睡在未来是一个时间戳醒来");
			LockSupport.parkUntil(System.currentTimeMillis() + 2000);
			
			System.out.println("11) " + formatter.format(new Date()) + " : " + "执行 parkUntil(blocker, deadline) 让线程沉睡在未来是一个时间戳醒来,并为主线程传递参数");
			String blocker2 = "我是 blocker2";
			LockSupport.parkUntil(blocker2, System.currentTimeMillis() + 2000);
			
			System.out.println("13) " + formatter.format(new Date()) + " : " + "定时 10 秒后重新启动,测试锁中断,中断时会立刻往下执行");
			LockSupport.parkUntil(System.currentTimeMillis() + 10000);
			
			System.out.println("15) " + formatter.format(new Date()) + " ==== 所有步骤执行完毕 ==== ");
		}
	}
	
	public static void main(String[] args) throws InterruptedException {
		Thread t1 = new Thread(new TestThread(), "线程 1");
		t1.start();
		
		Thread.sleep(2000);
		System.out.println("3) " + formatter.format(new Date()) + " : " + "执行 unpark(t1)  t1 重新运行 ");
		LockSupport.unpark(t1);
		
		Thread.sleep(2000);
		String blocker = (String) LockSupport.getBlocker(t1);
		System.out.println("5) " + formatter.format(new Date()) + " : " + "执行 getBlocker(t1) 从 t1  中获取到 blocker = " + blocker);
		System.out.println("6) " + formatter.format(new Date()) + " : " + "执行 unpark(t1)  t1 重新运行");
		LockSupport.unpark(t1);
		Thread.sleep(3000);
		String blocker1 = (String) LockSupport.getBlocker(t1);
		System.out.println("9) " + formatter.format(new Date()) + " : " + "执行 getBlocker(t1) 从 t1  中获取到 blocker1 = " + blocker1);
		
		Thread.sleep(5000);
		String blocker2 = (String) LockSupport.getBlocker(t1);
		System.out.println("12) " + formatter.format(new Date()) + " : " + "执行 getBlocker(t1) 从 t1  中获取到 blocker2 = " + blocker2);
		
		Thread.sleep(1000);
		System.out.println("14) " + formatter.format(new Date()) + " : " + "开始中断锁");
		t1.interrupt();
	}
}

输出结果

  1. 15:11:12:443 : 线程 1 进来了
  2. 15:11:12:443 : 执行普通 park() 让线程挂起
  3. 15:11:14:443 : 执行 unpark(t1) t1 重新运行
  4. 15:11:14:443 : 执行 park(blocker) 为主线程传递参数
  5. 15:11:16:443 : 执行 getBlocker(t1) 从 t1 中获取到 blocker = 我是 blocker
  6. 15:11:16:443 : 执行 unpark(t1) t1 重新运行
  7. 15:11:16:443 : 执行 parkNanos(nanos) 让线程沉睡 2 秒
  8. 15:11:18:444 : 执行 parkNanos(blocker, nanos) 让线程沉睡 2 秒,并为主线程传递参数
  9. 15:11:19:444 : 执行 getBlocker(t1) 从 t1 中获取到 blocker1 = 我是 blocker1
  10. 15:11:20:445 : 执行 parkUntil(deadline) 让线程沉睡在未来是一个时间戳醒来
  11. 15:11:22:445 : 执行 parkUntil(blocker, deadline) 让线程沉睡在未来是一个时间戳醒来,并为主线程传递参数
  12. 15:11:24:445 : 执行 getBlocker(t1) 从 t1 中获取到 blocker2 = 我是 blocker2
  13. 15:11:24:446 : 定时 10 秒后重新启动,测试锁中断,中断时会立刻往下执行
  14. 15:11:25:445 : 开始中断锁
  15. 15:11:25:445 : ==== 所有步骤执行完毕 ====

猜你喜欢

转载自blog.csdn.net/ocp114/article/details/82851890