本例是关于生产者和消费者之间关系的Java源码实现。
首先简单的说一下生产者和消费者之间的关系:
生产者负责产生数据,消费者负责使用(消耗)数据;
另外在消费者和生产者之间存有一个缓冲池,用于保存生产者生产的数据,也便于消费者直接从中获取数据。
在本例中我们将缓存池的大小设置成1个单位,即当生产者生产一个数据之后,消费者就将其消耗。
根据以上描述,我们开始写测试代码:
public static void main(String [ ] args) {
Resource res = new Resource ( );
Producer pro = new Producer ( res );
Consumer con = new Consumer ( res );
Thread t1 = new Thread ( pro );
Thread t2 = new Thread ( con );
t1.start ( );
t2.start ( );
}
class Producer implements Runnable {
public Resource res;
public Producer(Resource res) {
this.res = res;
}
@ Override
public void run() {
// TODO Auto-generated method stub
for ( int i = 0 ; i < 1000 ; i ++ ) {
res.prodeuce ( );
}
}
}
class Consumer implements Runnable {
public Resource res;
public Consumer(Resource res) {
this.res = res;
}
@ Override
public void run() {
// TODO Auto-generated method stub
for ( int i = 0 ; i < 1000 ; i ++ ) {
res.consumer ( );
}
}
以下开始介绍实现方法中较为常见(传统)的一种
class Resource {t count = 0;
boolean flag = false;
public synchronized void prodeuce() {
while ( flag ) {
try {
this.wait ( );
} catch ( InterruptedException e ) {
// TODO Auto-generated catch block
e.printStackTrace ( );
}
}
System.out.println ( Thread.currentThread ( ).getName ( )+ " produce " + ++ count );
flag = true;
this.notify ( );
}
public synchronized void consumer() {
while ( ! flag ) {
try {
this.wait ( );
} catch ( InterruptedException e ) {
// TODO Auto-generated catch block
e.printStackTrace ( );
}
}
System.out.println ( Thread.currentThread ( ).getName ( )
+ " consumer " + ++ count );
flag = false;
this.notify ( );
}
}
以下是JDK5以后对多线程提供的新的支持:
class Resource {
int count = 0;
boolean flag = false;
Lock lock = new ReentrantLock ( );
Condition con = lock.newCondition ( );
public void prodeuce() {
try {
lock.lock ( );
while ( flag ) {
try {
con.await ( );
} catch ( InterruptedException e ) {
// TODO Auto-generated catch block
e.printStackTrace ( );
}
}
System.out.println ( Thread.currentThread ( )
.getName ( )
+ " produce " + ++ count );
flag = true;
con.signalAll ( );
} finally {
lock.unlock ( );
}
}
public void consumer() {
try {
lock.lock ( );
while ( ! flag ) {
try {
con.await ( );
} catch ( InterruptedException e ) {
// TODO Auto-generated catch block
e.printStackTrace ( );
}
}
System.out.println ( Thread.currentThread ( )
.getName ( )
+ " comsumer " + ++ count );
flag = false;
con.signalAll ( );
} finally {
lock.unlock ( );
}
}