精华内容
下载资源
问答
  • Lock和synchronized

    2021-04-23 20:57:48
    Lock和synchronized的选择 总结来说,Lock和synchronized有以下几点不同: Lock是一个接口,而synchronized是Java中的关键字,synchronized是内置的语言实现; synchronized在发生异常时,会自动释放线程占有的锁,...

    Lock和synchronized的选择

    总结来说,Lock和synchronized有以下几点不同:

    1. Lock是一个接口,而synchronized是Java中的关键字,synchronized是内置的语言实现;
    2. synchronized在发生异常时,会自动释放线程占有的锁,因此不会导致死锁现象发生;而Lock在发生异常时,如果没有主动通过unLock()去释放锁,则很可能造成死锁现象,因此使用Lock时需要在finally块中释放锁;
    3. Lock可以让等待锁的线程响应中断,而synchronized却不行,使用synchronized时,等待的线程会一直等待下去,不能够响应中断;
    4. 通过Lock可以知道有没有成功获取锁,而synchronized却无法办到。
    5. Lock可以提高多个线程进行读操作的效率。
    6. 在性能上来说,如果竞争资源不激烈,两者的性能是差不多的,而当竞争资源非常激烈时(即有大量线程同时竞争),此时Lock的性能要远远优于synchronized。
    展开全文
  • Lock和Synchronized

    2019-06-05 08:48:34
    Lock和synchronized对比 转自: https://www.cnblogs.com/handsomeye/p/5999362.html 两者区别: 1.首先synchronized是java内置关键字,在jvm层面,Lock是个java类; 2.synchronized无法判断是否获取锁的状态,Lock...

    Lock和synchronized对比

    转自:
    https://www.cnblogs.com/handsomeye/p/5999362.html

    两者区别:

    1.首先synchronized是java内置关键字,在jvm层面,Lock是个java类,在jdk层面;
    2.synchronized无法判断是否获取锁的状态,Lock可以判断是否获取到锁;
    3.synchronized会自动释放锁(a 线程执行完同步代码会释放锁 ;b 线程执行过程中发生异常会释放锁),Lock需在finally中手工释放锁(unlock()方法释放锁),否则容易造成线程死锁;
    4.用synchronized关键字的两个线程1和线程2,如果当前线程1获得锁,线程2线程等待。如果线程1阻塞,线程2则会一直等待下去,而Lock锁就不一定会等待下去,如果尝试获取不到锁,线程可以不用一直等待就结束了;
    5.synchronized的锁可重入、不可中断、非公平,而Lock锁可重入、可中断、可公平(两者皆可)
    6.Lock锁适合大量同步的代码的同步问题,synchronized锁适合代码少量的同步问题。

    解释第5条中的synchronized不可中断:我们知道线程是可以被中断的,但是在一些特殊情况下不可被中断:IO和在synchronized块上等待时。举个例子,程序在尝试调用synchronized方法时(阻塞住等待获取锁)不可被中断,而当Lock获取锁被阻塞时可以被中断。

    Synchronized

    synchronized是java中的一个关键字,也就是说是Java语言内置的特性。
    如果一个代码块被synchronized修饰了,当一个线程获取了对应的锁,并执行该代码块时,其他线程便只能一直等待,等待获取锁的线程释放锁,而这里获取锁的线程释放锁只会有两种情况:
      1)获取锁的线程执行完了该代码块,然后线程释放对锁的占有;
      2)线程执行发生异常,此时JVM会让线程自动释放锁。
      那么如果这个获取锁的线程由于要等待IO或者其他原因(比如调用sleep方法)被阻塞了,但是又没有释放锁,其他线程便只能干巴巴地等待

    再举个例子:当有多个线程读写文件时,读操作和写操作会发生冲突现象,写操作和写操作会发生冲突现象,但是读操作和读操作不会发生冲突现象。
      但是采用synchronized关键字来实现同步的话,就会导致一个问题:
      如果多个线程都只是进行读操作,所以当一个线程在进行读操作时,其他线程只能等待无法进行读操作。

    Lock

    而Lock则可以解决上述问题。
    Lock提供了比synchronized更多的功能。但是要注意以下几点:
      1)Lock不是Java语言内置的,synchronized是Java语言的关键字,因此是内置特性。Lock是一个类,通过这个类可以实现同步访问;
      2)Lock和synchronized有一点非常大的不同,采用synchronized不需要用户去手动释放锁,当synchronized方法或者synchronized代码块执行完之后,系统会自动让线程释放对锁的占用;而Lock则必须要用户去手动释放锁,如果没有主动释放锁,就有可能导致出现死锁现象。

    Lock可以通过lock()、tryLock()、tryLock(long time, TimeUnit unit)和lockInterruptibly()四个方法来获取锁。通过unLock()方法来释放锁。

    lock()

    由于在前面讲到如果采用Lock,必须主动去释放锁,并且在发生异常时,不会自动释放锁。因此一般来说,使用Lock必须在try{}catch{}块中进行,并且将释放锁的操作放在finally块中进行,以保证锁一定被被释放,防止死锁的发生。通常使用Lock来进行同步的话,是以下面这种形式去使用的:

    Lock lock = ...;
    lock.lock();
    try{
        //处理任务
    }catch(Exception ex){
         
    }finally{
        lock.unlock();   //释放锁
    }
    

    lock()方法是平常使用得最多的一个方法,就是用来获取锁。如果锁已被其他线程获取,则进行等待。

    tryLock()

    tryLock()方法是有返回值的,它表示用来尝试获取锁,如果获取成功,则返回true,如果获取失败(即锁已被其他线程获取),则返回false,也就说这个方法无论如何都会立即返回。在拿不到锁时不会一直在那等待。
      tryLock(long time, TimeUnit unit)方法和tryLock()方法是类似的,只不过区别在于这个方法在拿不到锁时会等待一定的时间,在时间期限之内如果还拿不到锁,就返回false。如果如果一开始拿到锁或者在等待期间内拿到了锁,则返回true。

    Lock lock = ...;
    if(lock.tryLock()) {
         try{
             //处理任务
         }catch(Exception ex){
             
         }finally{
             lock.unlock();   //释放锁
         } 
    }else {
        //如果不能获取锁,则直接做其他事情
    }
    

    lockInterruptibly()

    lockInterruptibly()方法比较特殊,当通过这个方法去获取锁时,如果线程正在等待获取锁,则这个线程能够响应中断,即中断线程的等待状态。也就使说,当两个线程同时通过lock.lockInterruptibly()想获取某个锁时,假若此时线程A获取到了锁,而线程B只有在等待,那么对线程B调用threadB.interrupt()方法能够中断线程B的等待过程。
      由于lockInterruptibly()的声明中抛出了异常,所以lock.lockInterruptibly()必须放在try块中或者在调用lockInterruptibly()的方法外声明抛出InterruptedException。

    Lock实例

    1.ReentrantLock
      ReentrantLock,意思是“可重入锁”,关于可重入锁的概念在下一节讲述。ReentrantLock是唯一实现了Lock接口的类,并且ReentrantLock提供了更多的方法。下面通过一些实例看具体看一下如何使用ReentrantLock

    public class Test {
        private ArrayList<Integer> arrayList = new ArrayList<Integer>();
        private Lock lock = new ReentrantLock();    //注意这个地方
        public static void main(String[] args)  {
            final Test test = new Test();
             
            new Thread(){
                public void run() {
                    test.insert(Thread.currentThread());
                };
            }.start();
             
            new Thread(){
                public void run() {
                    test.insert(Thread.currentThread());
                };
            }.start();
        }  
         
        public void insert(Thread thread) {
            lock.lock();
            try {
                System.out.println(thread.getName()+"得到了锁");
                for(int i=0;i<5;i++) {
                    arrayList.add(i);
                }
            } catch (Exception e) {
                // TODO: handle exception
            }finally {
                System.out.println(thread.getName()+"释放了锁");
                lock.unlock();
            }
        }
    }
    
    

    2.ReadWriteLock
    ReadWriteLock也是一个接口,在它里面只定义了两个方法:Lock readLock();和Lock writeLock();
    一个用来获取读锁,一个用来获取写锁。也就是说将文件的读写操作分开,分成2个锁来分配给线程,从而使得多个线程可以同时进行读操作。下面的ReentrantReadWriteLock实现了ReadWriteLock接口。

    public class Test {
        private ReentrantReadWriteLock rwl = new ReentrantReadWriteLock();
         
        public static void main(String[] args)  {
            final Test test = new Test();
             
            new Thread(){
                public void run() {
                    test.get(Thread.currentThread());
                };
            }.start();
             
            new Thread(){
                public void run() {
                    test.get(Thread.currentThread());
                };
            }.start();
             
        }  
         
        public void get(Thread thread) {
            rwl.readLock().lock();
            try {
                long start = System.currentTimeMillis();
                 
                while(System.currentTimeMillis() - start <= 1) {
                    System.out.println(thread.getName()+"正在进行读操作");
                }
                System.out.println(thread.getName()+"读操作完毕");
            } finally {
                rwl.readLock().unlock();
            }
        }
    }
    

    锁的类型

    1.可重入锁

    如果锁具备可重入性,则称作为可重入锁。像synchronized和ReentrantLock都是可重入锁,可重入性在我看来实际上表明了锁的分配机制:基于线程的分配,而不是基于方法调用的分配。举个简单的例子,当一个线程执行到某个synchronized方法时,比如说method1,而在method1中会调用另外一个synchronized方法method2,此时线程不必重新去申请锁,而是可以直接执行方法method2。

    class MyClass {
        public synchronized void method1() {
            method2();
        }
         
        public synchronized void method2() {
             
        }
    }
    

    2.可中断锁

    可中断锁:顾名思义,就是可以相应中断的锁。
      在Java中,synchronized就不是可中断锁,而Lock是可中断锁。

    3.公平锁

    公平锁即尽量以请求锁的顺序来获取锁。比如同是有多个线程在等待一个锁,当这个锁被释放时,等待时间最久的线程(最先请求的线程)会获得该所,这种就是公平锁。
      非公平锁即无法保证锁的获取是按照请求锁的顺序进行的。这样就可能导致某个或者一些线程永远获取不到锁。
      在Java中,synchronized就是非公平锁,它无法保证等待的线程获取锁的顺序。
      而对于ReentrantLock和ReentrantReadWriteLock,它默认情况下是非公平锁,但是可以设置为公平锁。

    4.乐观锁与悲观锁

    Lock和synchronized都是悲观锁,CAS和版本号机制是乐观锁。

    5.共享锁(读锁)与排他锁(写锁)

    排它锁

    ReentrantLock和synchronized都是排他锁,也就是说,如果对象被Lock或synchronized锁住,那么它不可以被其他线程读或者写,读和写都是不行的。

    共享锁

    ReadWriteLock中的readLock()是共享锁,可以让多个线程进行读。

    展开全文
  • lock和synchronized

    2018-04-09 21:22:25
    run之前、开始:线程被设置为当前线程,开始执行run方法、阻塞:线程被暂停、死亡:线程结束1.lock和synchronized区别(1)synchronize是java的关键字,而lock是一个接口。(2)synchronize和lock都作为锁,...
    线程共有五个状态:
    新建:调用start之前、
    就绪:调用start之后。run之前、
    开始:线程被设置为当前线程,开始执行run方法、
    阻塞:线程被暂停、
    死亡:线程结束

    1.lock和synchronized区别
    (1)synchronize是java的关键字,而lock是一个接口。
    (2)synchronize和lock都作为锁,synchronize可以在线程synchronize方法完毕或堵塞的时候释放锁,而lock则需要在finally中手动释放锁,不然就有可能造成死锁的现象。
    (3)lock可以做到多线程同时进行读操作。如果有一个线程占用读锁,另外的线程需要申请写操作都需要等待第一个线程释放锁。
    如果有一个线程进行写操作的时候,第二个线程要进行读写操作都需要等待第一个线程释放锁。
    (4)lock可以读取知道线程是否成功获取锁。synchronize不行。
    (5)lock可以让等待的线程响应关闭,synchronize不行。


    2.Lock简单使用
    Lock是一个接口,里面有五个方法。ReentrantLock是lock接口唯一的实现类
          
        void lock();
        void lockInterruptibly() throws InterruptedException;
        boolean tryLock();
        boolean tryLock(long time, TimeUnit unit) throws InterruptedException;
        void unlock();

    lock()用于获取锁,unlock用户释放锁
    tryLock()用于查看线程是否成功获取锁,若成功返回true,否则返回false
    tryLock(long time, TimeUnit unit)和tryLock()类似,但可以加入一个时间参数,若在指定时间内都没有返回true则返回false
    lockInterruptibly()是lock类中获取锁的方法,如若线程1获取锁,线程2申请锁在等待过程中,可以使用thread2.interrupt()方法使线程2响应关闭
    //注意,如果需要正确中断等待锁的线程,必须将获取锁放在try catch外面,然后将InterruptedException抛出

    如何使用lock接口可以同时进行多线程读操作?
    ReadWriteLock也是一个接口,其中定义了两个方法。
        Lock readLock();
        Lock writeLock();
    获取读锁和获取写锁。也就是将文件的读写操作分开,从而使得可以有多线程进行读操作ReentrantReadWriteLock实现了ReadWriteLock接口。(调用获取读锁方法rwl.readLock().lock();



    3.锁的相关概念
    1.可重入锁
    synchronize和ReentrantLock()都是可重入锁,可重入性可以说就是锁的分配机制,基于线程的分配而不是基于调用方法的分配。比如在同一对象中有两个方法都加上了synchronize锁,在方法一取得锁的时候,在方法一内部调用方法二,如若synchronize不具备可重入性,那么在方法一调用方法二的时候,方法二需要再去申请锁,但是由于方法一已经取得了该锁,所以方法二永远都不可能申请到锁。
    2.可中断锁
    synchronize不是可中断锁,lock是可中断锁(使用lockInterruptibly()方法)。
    3.公平锁
    公平锁即按照线程请求锁的顺序来分配锁,在一个线程释放锁的时候,等待时间最久的那个线程先获得锁。
    synchronize为非公平锁。所以可能有一个线程永远都获取不到锁。
    lock默认为非公平锁,但是可以在实例化的时候:ReentrantLock lock = new ReentrantLock(true);来配置为公平锁。
    4.读写锁
    展开全文
  • lock synchronized

    2018-07-31 18:34:56
    Lock实现提供了比使用synchronized方法或者语句更有扩展性的锁定操作,有更多的属性,可以关联多个Condition。 锁是一种用于控制多个线程对共享资源的访问的工具。通常,锁提供对共享资源的独占访问,并且对共享...

    Lock实现提供了比使用synchronized方法或者语句更有扩展性的锁定操作,有更多的属性,可以关联多个Condition。

    锁是一种用于控制多个线程对共享资源的访问的工具。通常,锁提供对共享资源的独占访问,并且对共享资源的访问都需要先获得锁。但有的锁支持并发访问共享资源,如ReadWriteLock的读锁。

    synchronized方法或语句可以访问每个对象关联的隐式监视器锁,但获取和释放都必须以此块为单位,当获取多个锁时,必须在获取他们的此法范围内以相反的顺序释放。

    synchronized使得编程更加容易,但有时候需要更加灵活的使用方式,比如获取结点A的锁,然后获取结点B的锁,然后释放A并且获取C,然后释放B并且获取D,Lock接口的可以实现,允许在不同的范围内获取和释放锁,并允许以任何顺序获取和释放多个锁。但同时,synchronized是自己获取和释放锁,lock要求手动lock和unlock。

    当锁定和解锁发生在不同的范围内时,必须注意确保在保持锁定时执行的所有代码都受try-finally或try-catch保护,以确保在必要时释放锁。

    被synchronized修饰的程序块经过编译后,会在前后生成monitorenter和monitorexit两个字节码指令。为了实现互斥锁,JVM的monitorenter和monitorexit字节码依赖底层操作系统的互斥锁来实现,java层面的线程与操作系统的原生线程有映射关系,这时如果要将一个线程进行阻塞或唤起都需要操作系统的协助,这就需要从用户态切换到内核态来执行,这种切换代价十分昂贵,需要消耗很多处理器时间。如果可能,应该减少这样的切换。

    Synchronized还有另外一个重要的特性——可重入性。

    synchronized实现的是一个非公平锁,非公平主要表现在获取锁的行为上,并非是按照申请锁的时间前后给等待线程分配锁的,每当锁被释放后,任何一个线程都有机会竞争到锁,这样做的目的是为了提高执行性能,当然也会产生线程饥饿现象。

    synchronized最后一个特性(缺点)就是不可中断性,在所有等待的线程中,你们唯一能做的就是等,而实际情况可能是有些任务等了足够久了,我要取消此任务去干别的事情,此时synchronized是无法帮你实现的,它把所有实现机制都交给了JVM,提供了方便的同时也体现出了自己的局限性。

    展开全文
  • Lock Synchronized

    千次阅读 2018-10-05 12:05:56
    当有多个线程读写文件时,读操作写操作会发生冲突,读操作写操作发生冲突现象,但是读操作写操作不会发生冲突现象 但是采用sychronized关键字来实现同步的话,就会导致一个问题: 如果多个线程都只是读操作,当一...
  • Lock synchronized

    2016-05-31 16:56:26
    LOCK的优势:有读锁写锁 在等待时间,没有反应返回false,否则true 读多写少,希望比synchronized快点   并发: 简单程序(单节点)的synchronizedlock 多节点:比较多的是数据库的行级锁独立一个公共的...
  • lock 和synchronized

    2016-02-19 15:28:21
    synchronizedLock  最近在做一个监控系统,该系统主要包括对数据实时分析存储两个部分,由于并发量比较高,所以不可避免的使用到了一些并发的知识。为了实现这些要求,后台使用一个队列作为缓存,...
  • Java lock和synchronized

    2021-04-26 16:02:27
    lock和synchronized的区别 1、原始构成 synchronize是Java关键字属于JVM层面 使用monitorenter和monitorexit实现(底层是通过monitor对象来完成,wait、notify也是依赖于monitor对象,因此只有在同步块或者方法中...
  • Lock和synchronized的对比

    2021-02-15 14:49:39
    Lock和synchronized的对比 Lock是显式锁(手动开启和关闭锁)synchronized是隐式锁,除了作用域自动释放。 Lock只有代码块锁synchronized有代码块锁和方法锁 使用Lock锁,JVM将花费较少的时间来调度线程,性能更好,...
  • Lock和Synchronized的区别

    2021-06-07 23:35:35
    Lock和Synchronized的区别 Lock是显示锁(需要手动加锁和释放),Synchronized是隐式锁,出了作用域会自动释放。 Lock只作用于代码块,Synchronized即可作用于代码块,也可作用于方法上。 使用Lock锁,不会占用大量JVM...
  • lock和synchronized的区别

    2019-09-18 09:42:29
    lock和synchronized的区别 lock和synchronized的区别 一直以来java有很多的相似关键字或相似意义的字,不是很好区别和掌握,下边来说下这两个单词在Java中的基本概念和应用,我这个也是收百家之长来汇总的。 相同...
  • 基础理论知识,描述lock和synchronized的区别和基础的理论,其中还有死锁等基础概念。
  • Lock和synchronized的区别

    2020-09-01 09:36:34
    Lock和synchronized的区别 A. 结构不同 synchronized是java关键字是默认提供的,lock是jdk1.5开始支持的,本身是一个接口。 B. synchronized是隐式锁,Lock是显式锁 synchronized不需要用户手动去关闭,等到执行结束...
  • Lock和synchronized比较详解
  • Lock和synchronized的比较

    2017-09-07 22:49:16
    Lock和synchronized的选择 总结来说,Lock和synchronized有以下几点不同: 1)Lock是一个接口,而synchronized是Java中的关键字,synchronized是内置的语言实现; 2)synchronized在发生异常时,会自动释放线程...
  • 关于lock和synchronized的选择 这里不介绍具体用法,介绍lock和synchronized的不同从而做出选择 1.lock是一个接口,而synchronized是java中的一个关键字,synchronized是内置的语言实现。 2.synchronized在发生...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 6,965
精华内容 2,786
关键字:

lock和synchronized