Synchronized和Lock的区别

引言java

  在多线程中,为了使线程安全,咱们常常会使用synchronized和Lock进行代码同步和加锁,可是具体二者有什么区别,什么场景下适合用什么可能还不大清楚,主要的区别大体以下:安全

区别多线程

    一、synchronized是java关键字,而Lock是java中的一个接口ide

    二、synchronized会自动释放锁,而Lock必须手动释放锁测试

    三、synchronized是不可中断的,Lock能够中断也能够不中断spa

   四、经过Lock能够知道线程有没有拿到锁,而synchronized不能线程

    五、synchronized能锁住方法和代码块,而Lock只能锁住代码块code

    六、Lock能够使用读锁提升多线程读效率blog

    七、synchronized是非公平锁,ReentranLock能够控制是否公平锁接口

 

从Lock接口中咱们能够看到主要有5个方法,这些方法的功能从注释中能够看出:

1 lock():获取锁,若是锁被暂用则一直等待 
2 unlock():释放锁 
3 tryLock(): 注意返回类型是boolean,若是获取锁的时候锁被占用就返回false,不然返回true
4 tryLock(long time, TimeUnit unit):比起tryLock()就是给了一个时间期限,保证等待参数时间 
5 lockInterruptibly():用该锁的得到方式,若是线程在获取锁的阶段进入了等待,那么能够中断此线程,先去作别的事   经过 以上的解释,大体能够解释在上个部分中“锁类型(lockInterruptibly())”,“锁状态(tryLock())”等问题,还有就是前面子所获取的过程我所写的“大体就是能够尝试得到锁,线程能够不会一直等待”用了“能够”的缘由。

lock():

 1 public class LockTest {
 2     private Lock lock = new ReentrantLock();
 3 
 4     private void method(Thread thread) {
 5         lock.lock();
 6         try {
 7             System.out.println(thread.getName() + " has gotten the lock!");
 8         } catch (Exception e) {
 9             e.printStackTrace();
10         } finally {
11             System.out.println(thread.getName() + " has unlocked the lock!");
12             lock.unlock();
13         }
14     }
15 
16     public static void main(String[] args) {
17         final LockTest test = new LockTest();
18 
19         Thread t1 = new Thread(new Runnable() {
20             @Override
21             public void run() {
22                 test.method(Thread.currentThread());
23             }
24         }, "t1");
25         Thread t2 = new Thread(new Runnable() {
26             @Override
27             public void run() {
28                 test.method(Thread.currentThread());
29             }
30         }, "t2");
31         t1.start();
32         t2.start();
33     }
34 
35 }

运行结果:

t1 has gotten the lock!
t1 has unlocked the lock!
t2 has gotten the lock!
t2 has unlocked the lock!

 

tryLock():

 1 public class LockTest {
 2     private Lock lock = new ReentrantLock();
 3 
 4     private void method(Thread thread) {
 5     
 6         if (lock.tryLock()) {
 7             lock.lock();
 8             try {
 9                 System.out.println(thread.getName() + " has gotten the lock!");
10             } catch (Exception e) {
11                 e.printStackTrace();
12             } finally {
13                 System.out.println(thread.getName() + " has unlocked the lock!");
14                 lock.unlock();
15             }
16         } else {
17             System.out.println("I'm "+thread.getName()+". Someone has gotten the lock!");
18         }
19     }
20 
21     public static void main(String[] args) {
22         LockTest test = new LockTest();
23 
24         Thread t1 = new Thread(() -> test.method(Thread.currentThread()), "t1");
25         Thread t2 = new Thread(new Runnable() {
26             @Override
27             public void run() {
28                 test.method(Thread.currentThread());
29             }
30         }, "t2");
31         t1.start();
32         t2.start();
33     }
34 }

运行结果:

t1 has gotten the lock!
t1 has unlocked the lock!
I'm t2. Someone has gotten the lock!

看到这里相信你们也都会使用如何使用Lock了吧,关于tryLock(long time, TimeUnit unit)和lockInterruptibly()再也不赘述。前者主要存在一个等待时间,在测试代码中写入一个等待时间,后者主要是等待中断,会抛出一个中断异常,经常使用度不高,喜欢探究能够本身深刻研究。

相关文章
相关标签/搜索