`

LockSupport

阅读更多

LockSupport类是Java6(JSR166-JUC)引入的一个类,提供了基本的线程同步原语。

LockSupport实际上是调用了Unsafe类里的函数,归结到Unsafe里,只有两个函数:

 

public native void unpark(Thread jthread);  
public native void park(boolean isAbsolute, long time);  

 

isAbsolute参数是指明时间是绝对的,还是相对的。

 

仅仅两个简单的接口,就为上层提供了强大的同步原语。

先来解析下两个函数是做什么的。

unpark函数为线程提供“许可(permit)”,线程调用park函数则等待“许可”。

这个有点像信号量,但是这个“许可”是不能叠加的,“许可”是一次性的。

比如线程B连续调用了三次unpark函数,当线程A调用park函数就使用掉这个“许可”,如果线程A再次调用park,则进入等待状态。

 

注意,unpark函数可以先于park调用。比如线程B调用unpark函数,给线程A发了一个“许可”,那么当线程A调用park时,它发现已经有“许可”了,那么它会马上再继续运行。

实际上,park函数即使没有“许可”,有时也会无理由地返回,这点等下再解析。

park和unpark的灵活之处

上面已经提到,unpark函数可以先于park调用,这个正是它们的灵活之处。

 

一个线程它有可能在别的线程unPark之前,或者之后,或者同时调用了park,那么因为park的特性,它可以不用担心自己的park的时序问题,否则,如果park必须要在unpark之前,那么给编程带来很大的麻烦!!

 

考虑一下,两个线程同步,要如何处理?

在Java5里是用wait/notify/notifyAll来同步的。wait/notify机制有个很蛋疼的地方是,比如线程B要用notify通知线程A,那么线程B要确保线程A已经在wait调用上等待了,否则线程A可能永远都在等待。编程的时候就会很蛋疼。

 

另外,是调用notify,还是notifyAll?

notify只会唤醒一个线程,如果错误地有两个线程在同一个对象上wait等待,那么又悲剧了。为了安全起见,貌似只能调用notifyAll了。

 

park/unpark模型真正解耦了线程之间的同步,线程之间不再需要一个Object或者其它变量来存储状态,不再需要关心对方的状态。

 

举例:

park: 直接阻塞

public static void test2(){
		LockSupport.park();
		System.out.println("block.");
	}

 

unpark&park

 

public static void test1(){
		LockSupport.unpark(Thread.currentThread());
		System.out.println(LockSupport.getBlocker(Thread.currentThread()));;
		LockSupport.park();
		System.out.println("block.");
	}

 unpark&park&park (unpark只能许可一次)

 

public static void test1(){
		LockSupport.unpark(Thread.currentThread());
		System.out.println(LockSupport.getBlocker(Thread.currentThread()));;
		LockSupport.park();
		LockSupport.park();
		System.out.println("block.");
	}

 

 

park & unpark

public static void test4() throws Exception
	{
		Thread t = new Thread(new Runnable()
		{
			private int count = 0;

			@Override
			public void run()
			{
				long start = System.currentTimeMillis();
				long end = 0;

				while ((end - start) <= 1000)
				{
					count++;
					end = System.currentTimeMillis();
				}

				System.out.println("after 1 second.count=" + count);

			//等待或许许可
				LockSupport.park();
				System.out.println("thread over." + Thread.currentThread().isInterrupted());

			}
		});

		t.start();

		Thread.sleep(2000);

		// 中断线程
		LockSupport.unpark(t);

		
		System.out.println("main over");
	}

 


park&
interrupt:

 

public static void test3() throws Exception
	{
		Thread t = new Thread(new Runnable()
		{
			private int count = 0;

			@Override
			public void run()
			{
				long start = System.currentTimeMillis();
				long end = 0;

				while ((end - start) <= 1000)
				{
					count++;
					end = System.currentTimeMillis();
				}

				System.out.println("after 1 second.count=" + count);

			//等待或许许可
				LockSupport.park();
				System.out.println("thread over." + Thread.currentThread().isInterrupted());

			}
		});

		t.start();

		Thread.sleep(2000);

		// 中断线程
		t.interrupt();

		
		System.out.println("main over");
	}

 

分享到:
评论

相关推荐

    Java中LockSupport的使用.docx

    Java中的LockSupport是一个底层工具类,它在JDK 1.6版本中被引入到`java.util.concurrent.locks`包中,主要用于构建锁和其他同步工具类。LockSupport的核心功能是提供线程阻塞和唤醒的原语,这些功能在Java的并发...

    Java 多线程与并发(9-26)-JUC锁- LockSupport详解.pdf

    LockSupport是Java中用于多线程同步的一个工具类,它提供了一组基础的线程阻塞和解除阻塞的方法。这个类位于java.util.concurrent.locks包下,是实现并发编程中AQS(AbstractQueuedSynchronizer)框架的重要基础之一...

    Java并发编程之LockSupport、Unsafe详解.docx

    在Java并发编程中,LockSupport和Unsafe是两个关键的工具类,它们提供了底层的线程控制功能,使得开发者能够深入地管理和控制线程的行为。LockSupport是Java并发库中的一个核心工具类,它提供了线程的阻塞和唤醒功能...

    Java并发编程学习之Unsafe类与LockSupport类源码详析

    《深入解析Java并发编程:Unsafe类与LockSupport类源码剖析》 在Java并发编程领域,Unsafe类和LockSupport类是两个重要的底层工具类,它们提供了低级别的内存操作和线程控制,使得开发者能够实现高效的并发算法和...

    详解Java多线程编程中LockSupport类的线程阻塞用法

    在Java多线程编程中,LockSupport类是一个重要的工具,它提供了一种低级别的线程阻塞和唤醒机制。LockSupport并不像synchronized或java.util.concurrent.locks包中的Lock接口那样提供锁的完整功能,但它提供了两个...

    Java concurrency之LockSupport_动力节点Java学院整理

    Java concurrency之LockSupport Java concurrency之LockSupport是Java并发编程中的一种基础设施,用于创建锁和其他同步类的基本线程阻塞原语。LockSupport提供了一组函数来实现线程之间的同步和通信,使得开发者...

    java线程阻塞中断与LockSupport使用介绍

    `Thread.interrupt()` 方法是用于向线程发送中断请求,而`LockSupport` 是Java 5引入的一个低级别的线程同步工具,提供了比`synchronized` 和 `java.util.concurrent.locks` 包更细粒度的控制。下面我们将详细讨论这...

    LockSupportTester.zip

    LockSupport是Java并发编程中的一个重要工具类,位于`java.util.concurrent.locks`包下,它提供了线程阻塞和唤醒的底层支持。在Java多线程编程中,LockSupport主要用于构建锁和其他同步机制,比如ReentrantLock和...

    源码解析文件ScheduledThreadPoolExecutor

    ScheduledThreadPoolExecutor 使用DelayedWorkQueue来实现延迟任务的执行,并使用LockSupport.parkNanos 方法来阻塞当前线程,直到队列中有任务可用。 在 Java 中,ScheduledThreadPoolExecutor 是一个高效的线程池...

    android demo,locksuport的unpark一个线程。

    在Android开发中,`LockSupport` 是一个非常重要的工具类,它属于并发处理包 `java.util.concurrent.locks`。这个类提供了低级别的线程阻塞和唤醒机制,可以帮助开发者实现复杂的线程同步策略。在标题和描述中提到的...

    尚硅谷大厂面试题第三季周阳主讲

    【描述】提到的重点在于JUC(Java并发包)中的可重入锁概念,以及与之相关的锁机制,如LockSupport工具类的使用。此外,还提到了LockSupport如何实现线程的阻塞和唤醒,以及AbstractQueuedSynchronizer (AQS) 在锁和...

    基于JDK源码解析Java领域中的并发锁之设计与实现.pdf

    本文将基于JDK源码解析Java领域中的并发锁,探讨AQS基础同步器、LockSupport、Condition接口、Lock接口、ReadWriteLock接口以及自定义API操作的设计与实现。 一、AQS(AbstractQueuedSynchronizer)基础同步器的...

    尚硅谷面试题第三季1

    【部分内容】:章节内容主要涵盖Java基础,包括字符串常量池的行为,以及JUC(Java并发工具包)中的可重入锁原理和LockSupport的线程阻塞与唤醒机制。 1. **Java基础 - 字符串常量池** - 在JDK7及以上版本,字符串...

    Java基础笔记-8-16

    其中线程休眠中重点学习了sleep()方法、LockSupport类下的park()和unpark()方法、以及sleep()方法和park()方法的区别,此外需要注意的是,Interrupt()方法能够使调用特定方法而处于阻塞状态的线程恢复运行,但通常不...

    Java Unsafe类1

    这些操作在Java并发库的`LockSupport`类中被封装,`LockSupport.park()`和`LockSupport.unpark(Thread)`都是基于`Unsafe`实现的。这种机制在实现自定义同步原语时非常有用。 4. CAS(Compare and Swap)操作: CAS...

    java并发编程-AQS和JUC实战

    以上介绍了 Java 并发编程中几个重要的概念和技术,包括 `ReentrantLock`、`Condition`、`Semaphore`、`ReadWriteLock`、`CountDownLatch`、`CyclicBarrier` 和 `LockSupport`。这些技术为我们提供了丰富的并发控制...

    Java concurrency之锁_动力节点Java学院整理

    JUC包在Java 5引入,提供了更为丰富的锁机制和高级同步工具,如Lock接口、ReadWriteLock接口、LockSupport阻塞原语、Condition条件以及相关的抽象类和实现类。 - Lock接口:Lock提供了比`synchronized`更细粒度的...

    Java 多线程与并发(3-26)-Java 并发 - Java中所有的锁.pdf

    在Java中,`java.util.concurrent.locks.LockSupport.parkNanos()`和`LockSupport.parkUntil()`方法可以用来实现自旋锁。`ReentrantLock`内部就使用了自旋锁策略,它会根据当前系统环境和锁的状态决定是否进行自旋。...

Global site tag (gtag.js) - Google Analytics