紧接着Callable和线程池,再次接触java.util.concurrent并发包下的东西。Lock提供比synchronized更灵活的并发控制。Lock是java.util.concurrent.locks包下的接口,Lock 实现提供了比使用synchronized 方法和语句可获得的更广泛的锁定操作,它能以更优雅的方式处理线程同步问题。使用最多的Lock类是ReentrantLock。下面用它来实现上一篇日志中的打印机的例子:
import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock; public class Printer { private Lock lock = new ReentrantLock();// 锁对象 public void printLetters(char c) { lock.lock();// 得到锁 try { for(int i = 0; i<5; i++) { System.out.print(c); } System.out.println(); }finally { lock.unlock();// 释放锁 } } }
这样就实现了和sychronized一样的同步效果,值得一提的是,用sychronized修饰的方法或者语句块在代码执行完之后锁自动释放,而是用Lock需要我们手动释放锁,所以为了保证锁最终被释放(发生异常情况),要把互斥区放在try内,释放锁放在finally内。
读锁和写锁的使用:
以下内容转载来至:http://blog.csdn.net/ghsau/article/details/7461369
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
如果说这就是Lock,那么它不能成为同步问题更完美的处理方式,下面要介绍的是读写锁(ReadWriteLock),我们会有一种需求,在对数据进行读写的时候,为了保证数据的一致性和完整性,需要读和写是互斥的,写和写是互斥的,但是读和读是不需要互斥的,这样读和读不互斥性能更高些,来看一下不考虑互斥情况的代码原型:
public class ReadWriteLockTest { public static void main(String[] args) { final Data data = new Data(); for (int i = 0; i < 3; i++) { new Thread(new Runnable() { public void run() { for (int j = 0; j < 5; j++) { data.set(new Random().nextInt(30)); } } }).start(); } for (int i = 0; i < 3; i++) { new Thread(new Runnable() { public void run() { for (int j = 0; j < 5; j++) { data.get(); } } }).start(); } } } class Data { private int data;// 共享数据 public void set(int data) { System.out.println(Thread.currentThread().getName() + "准备写入数据"); try { Thread.sleep(20); } catch (InterruptedException e) { e.printStackTrace(); } this.data = data; System.out.println(Thread.currentThread().getName() + "写入" + this.data); } public void get() { System.out.println(Thread.currentThread().getName() + "准备读取数据"); try { Thread.sleep(20); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(Thread.currentThread().getName() + "读取" + this.data); } }
部分输出结果:
Thread-1准备写入数据 Thread-3准备读取数据 Thread-2准备写入数据 Thread-0准备写入数据 Thread-4准备读取数据 Thread-5准备读取数据 Thread-2写入12 Thread-4读取12 Thread-5读取5 Thread-1写入12
我们要实现写入和写入互斥,读取和写入互斥,读取和读取互斥,在set和get方法加入sychronized修饰符:
public synchronized void set(int data) {...} public synchronized void get() {...}
部分输出结果:
Thread-0准备写入数据 Thread-0写入9 Thread-5准备读取数据 Thread-5读取9 Thread-5准备读取数据 Thread-5读取9 Thread-5准备读取数据 Thread-5读取9 Thread-5准备读取数据 Thread-5读取9
我们发现,虽然写入和写入互斥了,读取和写入也互斥了,但是读取和读取之间也互斥了,不能并发执行,效率较低,用读写锁实现代码如下:
class Data { private int data;// 共享数据 private ReadWriteLock rwl = new ReentrantReadWriteLock(); public void set(int data) { rwl.writeLock().lock();// 取到写锁 try { System.out.println(Thread.currentThread().getName() + "准备写入数据"); try { Thread.sleep(20); } catch (InterruptedException e) { e.printStackTrace(); } this.data = data; System.out.println(Thread.currentThread().getName() + "写入" + this.data); } finally { rwl.writeLock().unlock();// 释放写锁 } } public void get() { rwl.readLock().lock();// 取到读锁 try { System.out.println(Thread.currentThread().getName() + "准备读取数据"); try { Thread.sleep(20); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(Thread.currentThread().getName() + "读取" + this.data); } finally { rwl.readLock().unlock();// 释放读锁 } } }
部分输出结果为:
Thread-4准备读取数据 Thread-3准备读取数据 Thread-5准备读取数据 Thread-5读取18 Thread-4读取18 Thread-3读取18 Thread-2准备写入数据 Thread-2写入6 Thread-2准备写入数据 Thread-2写入10 Thread-1准备写入数据 Thread-1写入22 Thread-5准备读取数据
相关推荐
主要介绍了深入解析Java并发编程中线程的同步与线程锁的使用,synchronized和lock是Java中最常见的控制线程的方法,需要的朋友可以参考下
Java多线程--避免同步机制带来的死锁问题及用Lock锁解决线程安全问题
线程同步Synchronized,监视器monitor和锁lock的关系2---马克-to-win java视频
主要介绍了Java线程同步Lock同步锁代码示例,首先介绍了Java线程同步的原理,然后对lock同步锁作了简要阐述,分享了代码示例,具有一定参考价值,需要的朋友可以了解下。
锁正是基于这种思路实现的一种线程同步机制。 在对共享数据加锁后,每个线程在访问共享数据时必须先申请相应的锁。一旦获得锁后,就可以访问共享数据,并且一个锁同一时刻只能被一个线程持有,这意味着获得锁后不会...
多线程的线程同步,线程通讯,Lock锁
在jdk1.5以后,JAVA提供了Lock类来实现和synchronized一样的功能,并且还提供了Condition来显示线程间通信。 Lock类是Java类来提供的功能,丰富的api使得Lock类的同步功能比synchronized的同步更强大。本文章的所有...
NoHttp核心架构之多线程通信、线程安全、线程同步;synchronized锁,Lock锁;具体讲解请移步博客:http://blog.csdn.net/yanzhenjie1003/article/details/50992468
在char04包里放置了Java中Lock类的知识的代码,内容如下: Lock类 Lock类其他功能 Condition类 Condition类其他功能 读写锁 在char05包里放置了生产者/消费者的知识的代码,内容如下: 一对一 生产者/消费...
NoHttp核心架构之多线程通信、线程安全、线程同步;synchronized锁,Lock锁;具体讲解请移步:http://blog.csdn.net/yanzhenjie1003/article/details/50992468
2.讲解了在多线程中对并发访问的控制, 主要就是synchronized的使用, 由于此关键字在使用上非常灵活, 所以书中用了很多案例来介绍此关键字的使用, 为读者学习同步相关内容打好坚实的基础。3.介绍线程并不是孤独的...
Java线程不安全分析,同步锁和Lock机制,哪个解决方案更好.docx
解决Java多线程同步的方法是在需要同步的方法签名中加入synchronized关键字,使用synchronized对需要进行同步的代码段进行同步,或使用JDK 5中提供的java.util.concurrent.lock包中的Lock对象。为解决多个线程对同一...
线程同步Synchronized,监视器monitor和锁lock的关系1---马克-to-win java视频
线程同步Synchronized,监视器monitor和锁lock的关系2---马克-to-win java视频
Lock 接口和 ReentrantLock 类:提供更灵活的线程同步机制。 Executor 框架和线程池:用于管理和调度线程的执行。 通过合理地创建和管理线程,我们可以实现复杂的并发执行逻辑,提高程序的性能和响应能力,并确保...
Java线程不安全分析,同步锁和Lock机制,哪个解决方案更好 (2).docx
为了避免数据不一致和竞争条件,项目使用了Java的同步机制(如synchronized关键字、Lock接口等)来确保线程安全。 3. 断点续传:项目基于Http协议实现了断点续传功能。当下载过程中出现异常或网络中断时,可以从...
23 IBM 的 Java 诊断,第 3 部分 使用面向 Java 的 Lock Analyzer 诊断同步和锁问题.mht 24 实现 Java 多线程并发控制框架.mht 25 多线程、多平台环境中的跟踪.mht 26 使用 ConTest 进行多线程单元测试.mht 27 ...
主要介绍了Java线程之锁对象Lock-同步问题更完美的处理方式代码实例,还是挺不错的,这里分享给大家,需要的朋友可以参考。