Java Concurrent Lock锁

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 thread
				ThreadFactory.createWriteThread(shareCache).start();
			}else{
				// create 10 read number thread
				ThreadFactory.createReadThread(shareCache).start();
			}
		}
	}
}

class ThreadFactory {
	private static Random random = new Random();

	public static Thread createWriteThread(final ShareCache shareCache) {
		return new Thread(new Runnable() {
			@Override
			public void run() {
				shareCache.incrementNumber();
			}
		});
	}

	public static Thread createReadThread(final ShareCache shareCache) {
		return new Thread(new Runnable() {
			@Override
			public void run() {
				System.out.println(Thread.currentThread().getName()
						+ " read number:" + shareCache.getNumber());
			}
		});
	}
}

class ShareCache {
	private Lock lock = new ReentrantLock();

	private int number = 0;

	// number increment
	public 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:1
Thread-1 read number:1
Thread-3 read number:1
Thread-5 read number:1
Thread-7 read number:1
Thread-9 read number:1
Thread-2 increment number:2
Thread-6 increment number:3
Thread-11 read number:3
Thread-13 read number:3
Thread-4 increment number:4
Thread-15 read number:4
Thread-10 increment number:5
Thread-17 read number:5
Thread-8 increment number:6
Thread-19 read number:6
Thread-12 increment number:7
Thread-14 increment number:8
Thread-16 increment number:9
Thread-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();
   }
  }
 }
}


 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值