Java5中新增了大量线程同步的功能,比如显式Lock,读写锁ReadWriteLock,条件变量Condition等,虽然这些功能使用之前的synchronized同步关键字都可能实现,但自己使用同步关键字不仅管理混乱,而且容易出错。 如下是使用显式Lock和条件变量Condition更好的解决生产者消费者问题,关于lock和condition读者可以自己查阅相关说明,也很好理解。
Consumer.java
package CreatorAndConsumer;
public class Consumer implements Runnable {
/**
* 线程资源
*/
private Plate plate;
public Consumer(Plate plate) {
this.plate = plate;
}
@Override
public void run() {
plate.getEgg();
}
}
Creator.java
package CreatorAndConsumer;
/**
* 生产者
*
* @author Martin
*/
public class Creator implements Runnable {
/**
* 线程资源
*/
private Plate plate;
public Creator(Plate plate) {
this.plate = plate;
}
@Override
public void run() {
Object egg = new Object();
plate.addEgg(egg);
}
}
Plate.java
package CreatorAndConsumer;
import java.util.List;
import java.util.concurrent.locks.*;
/**
* 盘子,表示共享的资源
*
* @author Martin
*/
public class Plate {
private List<Object> eggs = new ArrayList<Object>();
/**
* 锁
*/
private Lock lock;
/**
* 大于0条件变量,用于保证消费时有资源可消费
*/
private Condition more0Condition;
public Plate() {
lock = new ReentrantLock();
more0Condition = lock.newCondition();
}
/**
* 获取蛋
*
* @return
*/
public Object getEgg() {
lock.lock();
try {
while (eggs.size() < 1) {
more0Condition.await();
}
System.out.println("消费者取蛋,当前剩余:" + eggs.size());
Object egg = eggs.get(0);
eggs.remove(0);
return egg;
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
lock.unlock();
}
return null;
}
/**
* 加入蛋
*
* @return
*/
public void addEgg(Object egg) {
lock.lock();
System.out.println("生产者生蛋,当前剩余:" + eggs.size());
eggs.add(egg);
more0Condition.signalAll();
lock.unlock();
}
}
Tester.java
package CreatorAndConsumer;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class Tester {
public static void main(String[] args)
{
//共享资源
Plate plate = new Plate();
ExecutorService pool = Executors.newFixedThreadPool(100);
//添加生产者和消费者
for(int i = 0 ; i < 1000; i ++)
{
pool.execute(new Creator(plate));
pool.execute(new Consumer(plate));
}
pool.shutdown();
}
}
</pre><pre>