博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
简述synchronized和java.util.concurrent.locks.Lock的异同
阅读量:7075 次
发布时间:2019-06-28

本文共 1896 字,大约阅读时间需要 6 分钟。

hot3.png

简述synchronized和java.util.concurrent.locks.Lock的异同 

源码来自一篇Java基础题 
主要相同点:Lock能完成synchronized所实现的所有功能 
主要不同点:Lock有比synchronized更精确的线程语义和更好的性能。synchronized会自动释放锁,而Lock一定要求程序员手工释放,并且必须在finally从句中释放(因为如果不在finally中释放的情况,当抛出异常时,线程直接死掉,但是没有释放锁,使得其他相关线程无法执行。读者可以试试在定义一个数组,并访问越界区,使得程序抛出异常,但是释放锁并未在finally中)。

 

源码例子: 

Java代码 

  1. package test.thread;  
  2. import java.util.concurrent.locks.Lock;  
  3. import java.util.concurrent.locks.ReentrantLock;  
  4. public class TestLock {  
  5.     private int j;  
  6.     private Lock lock = new ReentrantLock();  
  7.     public static void main(String[] args) {  
  8.         TestLock tt = new TestLock();  
  9.         for (int i = 0; i < 2; i++) {  
  10.             new Thread(tt.new Adder()).start();  
  11.             new Thread(tt.new Subtractor()).start();  
  12.         }  
  13.     }  
  14.     private class Subtractor implements Runnable {  
  15.         @Override  
  16.         public void run() {  
  17.             for (int i = 0; i < 15; i++) {  
  18.                 // 这里抛异常了,锁能释放吗?会释放,但是lock就不会释放,所以需要加上try..catch  
  19.                 /*synchronized (TestLock.this) {  
  20.                     System.out.println("j--=" +j--); 
  21.                 }*/  
  22.                 lock.lock();  
  23.                 try {  
  24.                     System.out.println("j--=" + j--);  
  25.                 } finally {  
  26.                     lock.unlock();  
  27.                 }  
  28.             }  
  29.         }  
  30.     }  
  31.     private class Adder implements Runnable {  
  32.         @Override  
  33.         public void run() {  
  34.             for (int i = 0; i < 15; i++) {  
  35.                  /*synchronized (TestLock.this) { 
  36.                      System.out.println("j++="+j++);  
  37.                  }*/  
  38.                 lock.lock();  
  39.                 try {  
  40.                     System.out.println("j++=" + j++);  
  41.                 } finally {  
  42.                     lock.unlock();  
  43.                 }  
  44.             }  
  45.         }  
  46.     }  
  47. }  

Lock还有更强大的功能,例如,它的tryLock方法可以非阻塞方式去拿锁。 
tryLock() 
tryLock(long timeout, TimeUnit timeUnit) 
trylock()方法:如果获取了锁立即返回true,如果别的线程正持有锁,立即返回false; 
tryLock(long timeout, TimeUnit timeUnit)方法:如果获取了锁定立即返回true,如果别的线程正持有锁,会等待参数给定的时间,在等待的过程中,如果获取了锁定,就返回true,如果等待超时,返回false; 
是不是比synchronized灵活就体现出来了,比如:你现在正在忙于工作,突然感觉内急,于是你跑向洗手间,到门口发现一个“清洁中,暂停使用”的牌牌。没办法,工作又忙,所以你只好先放弃去洗手间回去忙工作,可能如此反复,终于你发现可以进了,于是...... 
如果用synchronized,当你发现洗手间无法暂时无法进入时,就只能乖乖在门口干等了。 
而使用trylock()呢,首先你试着去洗手间,发现暂时无法进入(trylock返回false),于是你继续忙你的工作,如此反复,直到可以进入洗手间为止(trylock返回true)。甚至,你非常急,你可以尝试性的在门口等20秒,不行再去忙工作(trylock(20, TimeUnit.SECONDS);)。 

转载于:https://my.oschina.net/liupengjun/blog/691235

你可能感兴趣的文章
等待实习的offer中的想法
查看>>
在Apache配置https方式访问网站
查看>>
线程开发之多线程之间的通讯实现
查看>>
全面分析 Spring 的编程式事务管理及声明式事务管理
查看>>
Leetcode——最长不重复子串
查看>>
myEclipse 中看jar源代码
查看>>
Linux awk 命令 说明
查看>>
shell之变量和引用
查看>>
两个基本概念 标称型数据和数值型数据
查看>>
MediaPlayer视频播放
查看>>
Android文本框实现搜索和清空效果
查看>>
Android的五种数据存储方式
查看>>
cookie的secure属性详解
查看>>
[Jquery] 实现鼠标移到某个对象,在旁边显示层。
查看>>
logrotate工具的使用
查看>>
我的友情链接
查看>>
华尔街为何弃苹果而力挺谷歌?因为谷歌无对手
查看>>
电脑蓝屏代码含义和解决方法
查看>>
Ubuntu server 14.04升级16.04
查看>>
Spring事务
查看>>