标签:Thread LockSupport son 线程 new public
1、为什么想着了解LockSupport ?
因为 LockSupport 在底层的使用较多,它比内置锁( synchronized 隐式锁)使用起来更方便。通常使用的“等待——通知”有3种 (还可通过Atomic类实现):
(1) ReetrantLock 提供了一个 newCondition 方法 获取到 ConditionObject对象,通过condition, 我们可以调用 await() 和 signal 方法;
(2) 通过调用Object的 wait 和 notify 方法。 wait和notifyAll必须写在同步代码块中,而同步一般用 synchronized ,JDK1.8及更高的版本也推荐使用 synchronized ;
(3) 通过 LockSupport 调用 park 和 unpark 方法;
具体什么情况下使用什么方式,需我们充分了解 这3种方式的优缺点。
通过第2种方式实现:
public static void main(String[] args) throws InterruptedException { final Object obj = new Object(); Thread son = new Thread(new Runnable() { public void run() { try { synchronized (obj) { obj.wait(); } } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("son thread"); } }); son.start(); Thread.sleep(100); //阻塞wait方法 synchronized (obj) { obj.notifyAll(); } }
缺点:当我们注释掉sleep后,可能线程son一直处于运行中,因为son线程不是后台线程。
通过第3种方式实现:
public static void main(String[] args) throws InterruptedException { Thread son = new Thread(new Runnable() { @Override public void run() { LockSupport.park(); System.out.println("son thread"); } }); son.start(); Thread.sleep(100); LockSupport.unpark(son); }
通过测试,主线程不执行sleep,son线程也会正常执行退出。这就是LockSupport的灵活性。
2、jdk中哪些类使用了LockSupport
(1)我们在实现一个线程时,如果我们需要线程返回结果,那么我们要实现callable。我们通过Future取到返回值。
public static void main(String[] args) throws InterruptedException, ExecutionException { ArrayBlockingQueue<Runnable> queue = new ArrayBlockingQueue<>(100); ThreadPoolExecutor pool = new ThreadPoolExecutor(4, 4, 100, TimeUnit.SECONDS, queue); Future<String> future = pool.submit(new Callable<String>() { @Override public String call() throws Exception { TimeUnit.MILLISECONDS.sleep(100); return UUID.randomUUID().toString(); } }); String result = future.get(); System.out.println(result); }
上面一段代码,当我们在使用future.get时,如果线程还没执行完,那么程序是不是有问题? 还是它会阻塞,等到线程执行完?
通过查看源码,可以找到结果。
继续深入awaitDone方法
可以看到awaitDone调用了LockSupport方法实现阻塞效果。那么线程怎么唤醒阻塞的线程了??? 当然是通过 run() 方法,猜想run执行完之后,通知等待线程。
查看set方法:
查看finishCompletion方法:
可以看到通知是用的unpark.
(2)上面main函数中使用了同步容器,其实jdk中容器都包含一个对象 Condition , Condition是个接口,它的实现类为ConditionObject。同步容器中维护了2个condition:notEmpty和notFull,调用await(),实际上就是ConditionObject的await()方法。
await()
另外:ConditionObject是 AbstractQueuedSynchronizer (AQS)的一个内部类。
3、LockSupport源码
lockSupport方法中调用的是 UNSAFE的native方法,需要openJDK查看。
park底层代码:
标签:Thread,LockSupport,son,线程,new,public 来源: https://www.cnblogs.com/greys/p/10775635.html
本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享; 2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关; 3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关; 4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除; 5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。