Java Concurrent Lock锁

来源:互联网 发布:vue.js 例子 编辑:程序博客网 时间:2024/06/05 10:44

Lock比传统线程模型中的Synchronied方式更加面向对象,与生活中的锁类似,锁本身也应该是一个对象.两个线程执行的代码段要实现同步互斥的效果,它们必须用同一个Lock对象,锁是在代表要操作的资源的类的内部方法中,而不是线程代码中.

class & interface

 

* Lock

interface of lock,

* ReentrantLock

basic implementation of Lock

* Condition

interface of condition,

* ReadWriteLock

interface, read/write version of Lock,

* ReentrantReadWriteLock

basic implementation of ReadWriteLock,

*

(1)下面看下Lock的使用方法:

package thread.lock;import java.util.Random;import java.util.concurrent.locks.Lock;import java.util.concurrent.locks.ReentrantLock;public class LockTest1 {public static void main(String[] args) {ShareCache shareCache = new ShareCache();for (int i = 0; i < 20; i++) {if (i % 2 == 0) {// create 10 write number threadThreadFactory.createWriteThread(shareCache).start();}else{// create 10 read number threadThreadFactory.createReadThread(shareCache).start();}}}}class ThreadFactory {private static Random random = new Random();public static Thread createWriteThread(final ShareCache shareCache) {return new Thread(new Runnable() {@Overridepublic void run() {shareCache.incrementNumber();}});}public static Thread createReadThread(final ShareCache shareCache) {return new Thread(new Runnable() {@Overridepublic void run() {System.out.println(Thread.currentThread().getName()+ " read number:" + shareCache.getNumber());}});}}class ShareCache {private Lock lock = new ReentrantLock();private int number = 0;// number incrementpublic void incrementNumber() {lock.lock();try {Thread.sleep(1000);number++;System.out.println(Thread.currentThread().getName()+ " increment number:" + number);} catch (InterruptedException e) {e.printStackTrace();} finally {lock.unlock();}}// 读数据可以不上锁public int getNumber() {int returnValue = 0;lock.lock();try {// 模拟读取数据的时间Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}returnValue = number;lock.unlock();return returnValue;}}

输出结果:

Thread-0 increment number:1Thread-1 read number:1Thread-3 read number:1Thread-5 read number:1Thread-7 read number:1Thread-9 read number:1Thread-2 increment number:2Thread-6 increment number:3Thread-11 read number:3Thread-13 read number:3Thread-4 increment number:4Thread-15 read number:4Thread-10 increment number:5Thread-17 read number:5Thread-8 increment number:6Thread-19 read number:6Thread-12 increment number:7Thread-14 increment number:8Thread-16 increment number:9Thread-18 increment number:10

 

Java多线程 Condition的使用
 

Condition  Object 监视器方法(waitnotify  notifyAll)分解成截然不同的对象,以便通过将这些对象与任意 Lock 实现组合使用,为每个对象提供多个等待 set(wait-set)。其中,Lock 替代了synchronized 方法和语句的使用,Condition 替代了 Object 监视器方法的使用

 

条件(也称为条件队列 条件变量)为线程提供了一个含义,以便在某个状态条件现在可能为 true 的另一个线程通知它之前,一直挂起该线程(即让其“等待”)。因为访问此共享状态信息发生在不同的线程中,所以它必须受保护,因此要将某种形式的锁与该条件相关联。等待提供一个条件的主要属性是:以原子方式 释放相关的锁,并挂起当前线程,就像 Object.wait 做的那样。

Condition 实例实质上被绑定到一个锁上。要为特定 Lock 实例获得 Condition 实例,请使用其newCondition() 方法。

下面写个Lock和Condition结合的使用方法:

package thread.lock;import java.util.Random;import java.util.concurrent.locks.Condition;import java.util.concurrent.locks.Lock;import java.util.concurrent.locks.ReentrantLock;public class LockConditionTest {  public static void main(String[] args) {  ShareObj obj = new ShareObj() ;  new Thread(new Producer(obj)).start() ;  new Thread(new Customer(obj)).start() ; }}class ShareObj{ private Object shareData =null ; private Random random = new Random() ; private Lock lock = new ReentrantLock() ; private Condition condition = lock.newCondition() ;  public void produceData() throws InterruptedException{  lock.lock() ;  while(shareData !=null){   condition.await() ;  }  System.out.println("produce data......");  Thread.sleep(1000) ;  int data = random.nextInt(100) ;  System.out.println("produce data:"+data);  shareData = new Integer(data) ;  condition.signal() ;  lock.unlock() ; } public void customerData() throws InterruptedException{  lock.lock() ;  while(shareData ==null){   condition.await() ;  }  System.out.println("custome data......");  Thread.sleep(1000) ;  System.out.println("customer data:"+shareData);  shareData = null ;  condition.signal() ;  lock.unlock() ; } }class Producer implements Runnable{ private ShareObj shareObj ; public Producer(ShareObj obj){  this.shareObj = obj ; } @Override public void run() {  while(true){   try {    shareObj.produceData() ;   } catch (InterruptedException e) {    e.printStackTrace();   }  } }}class Customer implements Runnable{ private ShareObj shareObj ; public Customer(ShareObj obj){  this.shareObj = obj ; } @Override public void run() {  while(true){   try {    shareObj.customerData() ;   } catch (InterruptedException e) {    e.printStackTrace();   }  } }}