synchronized和lock的区别

原文摘自: https://www.eyesmoons.com/article/75

1,原始构成

synchronized是关键字,属于JVM层面,通过wait,notify和notifyAll来调度线程。

Lock是具体类,是api层面的锁。

2,使用方法

synchronized不需要用户手动去释放锁, 当synchronized代码执行完后,系统会自动释放锁。

Lock需要用户手动释放锁,否则会出现死锁现象。需要lock和unlock配合try/finally语句块来完成。

3,等待是否中断

synchronized不可中断,除非抛出异常或者正常运行完毕。

Lock可中断,可以设置超时方法或者调用中断方法。

4,加锁是否公平

synchronized非公平锁。

Lock默认非公平锁,可指定为公平锁。

5,锁绑定多个条件condition

synchronized没有。

Lock用来分组唤醒需要唤醒的线程,可以精确唤醒,而不是像synchronized一样要么随机唤醒一个线程,要么全部唤醒。

 

Demo: 练习

  多线程之间按顺序调用,实现A->B->C三个线程启动,要求:AA打印5次,BB打印10次,CC打印15次,重复10遍。

package com.demo.lock;

import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

class ShareResource{
    int number = 1;
    private Lock lock = new ReentrantLock();
    
    private Condition c1 = lock.newCondition();
    private Condition c2 = lock.newCondition();
    private Condition c3 = lock.newCondition();
    
    public void print5(){
        lock.lock();
        try {
            while(number!=1){
                c1.await();
            }
            for(int i=1;i<=5;i++){
                System.out.println(Thread.currentThread().getName()+"\t"+i);
            }
            number = 2;
            c2.signal();
        } catch (Exception e) {
            e.printStackTrace();
        }finally{
            lock.unlock();
        }
    }
    
    public void print10(){
        lock.lock();
        try {
            while(number!=2){
                c2.await();
            }
            for(int i=1;i<=10;i++){
                System.out.println(Thread.currentThread().getName()+"\t"+i);
            }
            number = 3;
            c3.signal();
        } catch (Exception e) {
            e.printStackTrace();
        }finally{
            lock.unlock();
        }
    }
    
    public void print15(){
        lock.lock();
        try {
            while(number!=3){
                c3.await();
            }
            for(int i=1;i<=15;i++){
                System.out.println(Thread.currentThread().getName()+"\t"+i);
            }
            number = 1;
            c1.signal();
        } catch (Exception e) {
            e.printStackTrace();
        }finally{
            lock.unlock();
        }
    }
}
public class TestReentrantLock {

    public static void main(String[] args) {
        ShareResource shareResource = new ShareResource();
        
        new Thread(()->{
            for(int i=1;i<=10;i++){
                shareResource.print5();
            }
        },"AA").start();
        
        new Thread(()->{
            for(int i=1;i<=10;i++){
                shareResource.print10();
            }
        },"BB").start();
        
        new Thread(()->{
            for(int i=1;i<=10;i++){
                shareResource.print15();
            }
        },"CC").start();
    }
}

 

posted @ 2019-08-17 12:48  北方有鱼  阅读(239)  评论(0编辑  收藏  举报