zoukankan      html  css  js  c++  java
  • synchronized和lock有什么区别?

    一、原始构成

    synchronized是关键字属于JVM层面,monitorenter(底层是通过monitor对象来完成,其实wait/notify等方法也依赖monitor对象只有在同步代码块和同步方法中才能调用wait/notify等方法)

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

    二、使用方法

    synchronized不需要用户手动释放锁,synchronized代码执行完成以后系统会自动让线程释放对锁的占有

    ReentrantLock则需要用户手动去释放锁,若没有主动释放锁,就有可能导致死锁现象。需要使用lock()和unlock()方法配合try finally语句块来完成。

    三、等待是否可以中断

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

    ReetrantLock可中断,

      1. 设置超时方法tryLock(long timeout, TimeUnit unit);

      2.lockInterruptibly()放入代码块中,调用interrupt()方法可中断;

    四、加锁是否公平

    synchronized是非公平锁

    ReentrantLock默认是非公平锁,可设置为公平锁。

    五、锁绑定多个条件condition

    synchronized没有; 

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

    六、案例

    题目:多线程之间按找顺序调用,实现A->B->C三个线程启动,要求如下:

    AA打印5次,BB打印10次,CC打印15次,重复上述过程10次.

    class ShareResource{
        private int number = 1; // A:1, B:2, C:3
        private Lock lock = new ReentrantLock();
        private Condition conditionA = lock.newCondition();
        private Condition conditionB = lock.newCondition();
        private Condition conditionC = lock.newCondition();
        public void print5(){
            try {
                lock.lock();
                while (number != 1){
                    conditionA.await();
                }
    
                for (int i = 1; i <= 5; i++){
                    System.out.print("A");
                }
                System.out.println();
                number++;
                conditionB.signal();
            } catch (InterruptedException e) {
                e.printStackTrace();
            } finally {
                lock.unlock();
            }
        }
        public void print10(){
            try {
                lock.lock();
                while (number != 2){
                    conditionB.await();
                }
    
                for (int i = 1; i <= 10; i++){
                    System.out.print("B");
                }
                System.out.println();
                number++;
                conditionC.signal();
            } catch (InterruptedException e) {
                e.printStackTrace();
            } finally {
                lock.unlock();
            }
        }
    
        public void print15(){
            try {
                lock.lock();
                while (number != 3){
                    conditionC.await();
                }
    
                for (int i = 1; i <= 15; i++){
                    System.out.print("C");
                }
                System.out.println();
                number = 1;
                conditionA.signal();
            } catch (InterruptedException e) {
                e.printStackTrace();
            } finally {
                lock.unlock();
            }
        }
    }
    public class SynchronizedLockDifference {
    
        public static void main(String[] args) {
            ShareResource shareResource = new ShareResource();
            new Thread(()->{
                for (int i = 1; i <= 10; i++){
                    shareResource.print5();
                }
            }, "A").start();
    
            new Thread(()->{
                for (int i = 1; i <= 10; i++){
                    shareResource.print10();
                }
            }, "B").start();
    
            new Thread(()->{
                for (int i = 1; i <= 10; i++){
                    shareResource.print15();
                }
            }, "C").start();
    
        }
    }

    输出结果:

    AAAAA
    BBBBBBBBBB
    CCCCCCCCCCCCCCC
    AAAAA
    BBBBBBBBBB
    CCCCCCCCCCCCCCC
    AAAAA
    BBBBBBBBBB
    CCCCCCCCCCCCCCC
    AAAAA
    BBBBBBBBBB
    CCCCCCCCCCCCCCC
    AAAAA
    BBBBBBBBBB
    CCCCCCCCCCCCCCC
    AAAAA
    BBBBBBBBBB
    CCCCCCCCCCCCCCC
    AAAAA
    BBBBBBBBBB
    CCCCCCCCCCCCCCC
    AAAAA
    BBBBBBBBBB
    CCCCCCCCCCCCCCC
    AAAAA
    BBBBBBBBBB
    CCCCCCCCCCCCCCC
    AAAAA
    BBBBBBBBBB
    CCCCCCCCCCCCCCC
    
    Process finished with exit code 0
  • 相关阅读:
    需求墙,挺有创意
    产品分析套路
    复杂问题的拆解分析,有点意思
    xss如何加载远程js的一些tips
    一次有趣的XSS漏洞挖掘分析(3)最终篇
    一次有趣的XSS漏洞挖掘分析(2)
    一次有趣的XSS漏洞挖掘分析(1)
    Java和WebSocket开发网页聊天室
    Socket.IO聊天室~简单实用
    C语言基于GTK+Libvlc实现的简易视频播放器(二)
  • 原文地址:https://www.cnblogs.com/ch-forever/p/10788674.html
Copyright © 2011-2022 走看看