Java同步锁------synchronized和lock
2018-01-24 16:40
302 查看
Synchronized
synchronized可用很好的解决多线程并发安全问题,但是在有些时候,他会使机器的性能降低,就比如在同步锁内部发生IO阻塞,导致了其他想获得锁的线程不能获得,一直阻塞在那里,这样大大降低的程序的运行效率。
经过总结synchronized有如下缺点:
(1)如果获得锁的线程发生了IO阻塞,或者调用了sleep方法,那么这样jvm是不会释放锁的(当线程发生异常,jvm才会让线程自动释放锁),这么一来,在阻塞过程中,cpu就空转了,其他线程得不到锁,这样降低了机子的性能。
(2)如果多线程进行读写文件时,读操作和写操作会发生冲突,写操作和写操作会发生冲突,读操作和写操作不会发生冲突,但是采用了synchronized,无论以上哪种情况,都会阻塞,我们知道,读操作和读操作是可用并发执行的,如果不阻塞可用提高性能。
综合以上2个缺点:就有了lock。lock可以很好的解决以上问题,针对第一个,lock可以通过设置锁的超时时间,超过设定时间就自动释放锁;针对第二点,lock就有相应的读锁和写锁。
Lock
lock是个接口,接口中有四个方法lock()、trylock()、trylock(long time, TimeUnit unit)、lockInterruptibly()来获取锁。
用unlock()来释放锁。
(1)lock是平常使用最多的一个方法,lock必须手动释放,在发生异常的时候,jvm是不会取释放锁的,因此在用lock时候,要写在try{}catch{}里面,并且在finally{}中去释放锁,避免死锁。
(2)trylock(),字面理解尝试获得锁,当trylock获得成功,就返回true,否则返回false,优点在于在拿不到锁的时候,不会一直等待,而会继续执行其他。
(3)trylock(long time, TimeUnit unit)和trylock()类似,就是多了参数,表示在指定时间仍然不能获取锁,那么返回false,否则返回true。
(4)lockInterruptibly(),举例:两个线程A、B通过lock.lockInterruptibly()获取锁,A先获得锁,B只能等待,那么B可以调用interrupt(),来中断B的等待。
lock需要我们自己去实现,显然不方便,那么就有ReentrantLock实现类,意思是“可重入锁”。
ReadWriteLock
ReadWriteLock是接口;其实现类是ReentrantReadWriteLock,主要有两个方法:readLock()和writeLock()
注意:
不过要注意的是,如果有一个线程已经占用了读锁,则此时其他线程如果要申请写锁,则申请写锁的线程会一直等待释放读锁。如果有一个线程已经占用了写锁,则此时其他线程如果申请写锁或者读锁,则申请的线程会一直等待释放写锁。
synchronized可用很好的解决多线程并发安全问题,但是在有些时候,他会使机器的性能降低,就比如在同步锁内部发生IO阻塞,导致了其他想获得锁的线程不能获得,一直阻塞在那里,这样大大降低的程序的运行效率。
经过总结synchronized有如下缺点:
(1)如果获得锁的线程发生了IO阻塞,或者调用了sleep方法,那么这样jvm是不会释放锁的(当线程发生异常,jvm才会让线程自动释放锁),这么一来,在阻塞过程中,cpu就空转了,其他线程得不到锁,这样降低了机子的性能。
(2)如果多线程进行读写文件时,读操作和写操作会发生冲突,写操作和写操作会发生冲突,读操作和写操作不会发生冲突,但是采用了synchronized,无论以上哪种情况,都会阻塞,我们知道,读操作和读操作是可用并发执行的,如果不阻塞可用提高性能。
综合以上2个缺点:就有了lock。lock可以很好的解决以上问题,针对第一个,lock可以通过设置锁的超时时间,超过设定时间就自动释放锁;针对第二点,lock就有相应的读锁和写锁。
Lock
lock是个接口,接口中有四个方法lock()、trylock()、trylock(long time, TimeUnit unit)、lockInterruptibly()来获取锁。
用unlock()来释放锁。
(1)lock是平常使用最多的一个方法,lock必须手动释放,在发生异常的时候,jvm是不会取释放锁的,因此在用lock时候,要写在try{}catch{}里面,并且在finally{}中去释放锁,避免死锁。
(2)trylock(),字面理解尝试获得锁,当trylock获得成功,就返回true,否则返回false,优点在于在拿不到锁的时候,不会一直等待,而会继续执行其他。
(3)trylock(long time, TimeUnit unit)和trylock()类似,就是多了参数,表示在指定时间仍然不能获取锁,那么返回false,否则返回true。
(4)lockInterruptibly(),举例:两个线程A、B通过lock.lockInterruptibly()获取锁,A先获得锁,B只能等待,那么B可以调用interrupt(),来中断B的等待。
lock需要我们自己去实现,显然不方便,那么就有ReentrantLock实现类,意思是“可重入锁”。
ReadWriteLock
ReadWriteLock是接口;其实现类是ReentrantReadWriteLock,主要有两个方法:readLock()和writeLock()
注意:
不过要注意的是,如果有一个线程已经占用了读锁,则此时其他线程如果要申请写锁,则申请写锁的线程会一直等待释放读锁。如果有一个线程已经占用了写锁,则此时其他线程如果申请写锁或者读锁,则申请的线程会一直等待释放写锁。
相关文章推荐
- 深入浅出Java并发包—锁(Lock)VS同步(synchronized)
- Java线程同步的解决方案——synchronized与Lock
- java实现同步map的几种方法(lock,synchronized,rwlock,ConcurrentHashMap,hashtable,SynchronizedMap)
- 【Java基础之线程同步(二)】java线程同步:synchronized关键字,Lock接口以及可重入锁ReentrantLock
- Java并发--互斥同步--synchronized和ReentrantLock比较
- java中lock与synchronized同步的解析
- Java并发--互斥同步--Java两种锁机制synchronized和ReentrantLock详解
- java 同步synchronized,lock(obj) ,读写锁
- Java多线程简析——Synchronized(同步锁)、Lock以及线程池
- java线程同步的三种方法[synchronized关键字,Lock加锁,信号量Semaphore]
- Java乐观锁悲观锁、synchronized,重入锁 (ReentrantLock)处理并发(互斥同步、非互斥同步)
- java同步关键词解释、synchronized、线程锁(Lock)
- java并发包中的Condition和Lock 取代Synchronized、wait、notify/notifyAll实现线程的同步与互斥
- java线程同步:synchronized关键字,Lock接口以及可重入锁ReentrantLock
- 深入浅出Java并发—锁(Lock)VS同步(synchronized)
- 深入浅出Java并发包—锁(Lock)VS同步(synchronized)
- java中多线程模拟(多生产,多消费,Lock实现同步锁,替代synchronized同步代码块)
- java学习--同步机制lock和synchronized对比学习
- 深入浅出Java并发包—锁(Lock)VS同步(synchronized)