Java多线程Lock

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Java多线程Lock相关的知识,希望对你有一定的参考价值。

JDK5以后为代码的同步提供了更加灵活的Lock+Condition模式,并且一个Lock可以绑定多个Condition对象

1.把原来的使用synchronized修饰或者封装的代码块用lock.lock()与lock.unlock()进行手动的锁获取与释放

//原来的同步方式
synchronized (obj) {
	...
}

//JDK5.0新增的同步方式
//lock.unlock();建议最好要放在finally 执行
try {
	lock.lock();
	...
} finally {
	lock.unlock();
}

2.把原来线程之间的通讯方式由锁对线obj.wait()和obj.notify()改成了Condition对象的con.await()与con.signal()方法

如下用Lock的方式重写多生产者多消费者模式时,线程可以指定唤醒生产者或者消费者,这样拥有更高的效率与安全性

 
package jdk5lockDome;

import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

/**
 * @author wpy
 * 
 */
public class ProducerConsumer {
	public static void main(String[] args) {
		Resource resource = new Resource();

		Producer producer0 = new Producer(resource);
		Producer producer1 = new Producer(resource);

		Consumer consumer2 = new Consumer(resource);
		Consumer consumer3 = new Consumer(resource);

		Thread t0 = new Thread(producer0);
		Thread t1 = new Thread(producer1);
		Thread t2 = new Thread(consumer2);
		Thread t3 = new Thread(consumer3);

		t0.start();
		t1.start();

		t2.start();
		t3.start();

	}

}

class Producer implements Runnable {
	private Resource resource;

	public Producer(Resource resource) {
		this.resource = resource;
	}

	@Override
	public void run() {
		while (true) {
			resource.set("资源");
		}
	}
}

class Consumer implements Runnable {
	private Resource resource;

	public Consumer(Resource resource) {
		this.resource = resource;
	}

	@Override
	public void run() {
		while (true) {
			resource.out();
		}
	}
}

class Resource {
	private String name;
	private int count = 1;
	// 是否生成完毕
	private boolean flag = false;

	/**
	 * 互斥锁(同时只有一个线程拥有锁)
	 */
	private Lock lock = new ReentrantLock();
	private Condition producerCon = lock.newCondition();
	private Condition consumerCon = lock.newCondition();

	/**
	 * 生产方法
	 * 
	 * @param name
	 */
	public void set(String name) {
		try {
			lock.lock();
			String threadName = Thread.currentThread().getName();
			while (flag) {
				System.out.println(threadName + "进入等待状态");
				producerCon.await();
			}
			System.out.println(threadName + "取得执行权");

			this.name = name + count;
			count++;
			System.out.println("生产者:" + this.name);
			flag = true;
			consumerCon.signal();
		} catch (InterruptedException e) {
			e.printStackTrace();
		} finally {
			lock.unlock();
		}
	}

	/**
	 * 消费方法
	 */
	public void out() {
		try {
			lock.lock();
			String threadName = Thread.currentThread().getName();
			while (!flag) {
				System.out.println(threadName + "进入等待状态");
				consumerCon.await();
			}
			System.out.println(threadName + "取得执行权");

			System.out.println("============消费者:" + name);
			flag = false;
			producerCon.signal();
		} catch (InterruptedException e) {
			e.printStackTrace();
		} finally {
			lock.unlock();
		}
	}
}

  

  


以上是关于Java多线程Lock的主要内容,如果未能解决你的问题,请参考以下文章

Java多线程与并发库高级应用-工具类介绍

Java多线程Lock

Java多线程学习篇Lock

Java多线程编程中的lock使用源码详解

Java多线程 Lock接口,ReentranctLock,ReentrantReadWriteLock

Java多线程学习之Lock与ReentranLock详解