实现功能:生产者一次生产一个数据,消费者每次消费一个数据(两个线程)
分别用lock+boolean类型标记值和lock+condition两种方法实现控制线程间的通信。代码如下:
package
Thread;
/**
*
@author
YHYR
*/
import
java.util.concurrent.locks.Condition;
import
java.util.concurrent.locks.Lock;
import
java.util.concurrent.locks.ReentrantLock;
public
class
ProduceAndCustomerDemo {
public
static
void
main(String[]
args
) {
Resource
res
=
new
Resource();
Produce
pro
=
new
Produce(
res
);
Customer
cus
=
new
Customer(
res
);
Thread
proThread
=
new
Thread(
pro
);
Thread
cusThread
=
new
Thread(
cus
);
proThread
.start();
cusThread
.start();
}
}
class
Produce
implements
Runnable {
Resource
res
;
public
Produce(Resource
res
) {
//
TODO
Auto-generated constructor stub
this
.
res
=
res
;
}
@Override
public
void
run() {
//
TODO
Auto-generated method stub
while
(
true
) {
try
{
Thread. sleep(100);
res
.produceResource();
}
catch
(InterruptedException
e
) {
//
TODO
Auto-generated catch block
e
.printStackTrace();
}
}
}
}
class
Customer
implements
Runnable {
Resource
cus
;
public
Customer(Resource
cus
) {
//
TODO
Auto-generated constructor stub
this
.
cus
=
cus
;
}
@Override
public
void
run() {
//
TODO
Auto-generated method stub
while
(
true
) {
try
{
Thread. sleep(100);
cus
.customerResource();
}
catch
(InterruptedException
e
) {
//
TODO
Auto-generated catch block
e
.printStackTrace();
}
}
}
}
class
Resource {
private
int
count
=0;
private
boolean
flag
=
false
;
private
Lock
lock
=
new
ReentrantLock();
private
Condition
condition
=
lock
.newCondition();
/**
* 写法一:只通过lock和flag,控制好逻辑判断,来实现线程安全
* 逻辑判断:当有可操作数据时,才执行响应的逻辑操作,否则直接解锁释放执行权
*/
public
void
produceResource() {
lock
.lock();
try
{
System.
out
.println(
"********************生产者抢到cpu"
);
while
(!
flag
) {
//没有数据,则启动生产者
System.
out
.println(
"********************生产者未检测到有可消费的数据,开始生产数据"
);
count
++;
System.
out
.println(Thread. currentThread().getName() +
" 生产者 ---->"
+
count
);
flag
=
true
;
}
System.
out
.println(
"********************数据已生产,等待消费者消费"
);
}
finally
{
lock
.unlock();
System.
out
.println();
}
}
public
void
customerResource() {
lock
.lock();
try
{
System.
out
.println(
"消费者抢到cpu"
);
while
(
flag
) {
//若有数据,启动消费者
System.
out
.println(
"消费者检测到资源,开始消费数据。。。。。。。。"
);
System.
out
.println(Thread. currentThread().getName() +
" 消费者 -----------> "
+
count
);
flag
=
false
;
}
System.
out
.println(
"未检测到可供消费的数据,等待生产者生产数据"
);
}
finally
{
lock
.unlock();
System.
out
.println();
}
}
/**
* 写法2;通过lock和condition实现线程安全
* 逻辑判断:如果没有可操作的数据,则挂起该线程,并释放CPU执行权
* 如果使用condition.singal()方法,可能会导致死锁
*
@throws
InterruptedException
*/
/* public void produceResource() throws InterruptedException {
lock.lock();
try {
while(flag) //没有数据,则挂起该线程,并释放执行权
condition.await();
count++;
System.out.println(Thread.currentThread().getName() + " 生产者 ---->" + count);
flag = true;
condition.signalAll();;
} finally {
lock.unlock();
}
}
public void customerResource() throws InterruptedException {
lock.lock();
try {
while(!flag) //若没有数据,则挂起该消费者线程,并释放执行权
condition.await();
System.out.println(Thread.currentThread().getName() + " 消费者 -----------> " + count);
flag = false;
condition.signalAll();
} finally {
lock.unlock();
}
}*/
}
package
Thread;
import
java.util.concurrent.locks.Condition;
import
java.util.concurrent.locks.Lock;
public
class
ProduceAndCustomerDemo {
public
static
void
main(String[]
args
) {
Resource
res
=
new
Resource();
Produce
pro
=
new
Produce(
res
);
Customer
cus
=
new
Customer(
res
);
Thread
proThread
=
new
Thread(
pro
);
Thread
cusThread
=
new
Thread(
cus
);
proThread
.start();
cusThread
.start();
}
}
class
Produce
implements
Runnable {
Resource
res
;
public
Produce(Resource
res
) {
//
TODO
Auto-generated constructor stub
this
.
res
=
res
;
}
@Override
public
void
run() {
//
TODO
Auto-generated method stub
while
(
true
) {
try
{
Thread. sleep(100);
res
.produceResource();
}
catch
(InterruptedException
e
) {
//
TODO
Auto-generated catch block
e
.printStackTrace();
}
}
}
}
class
Customer
implements
Runnable {
Resource
cus
;
public
Customer(Resource
cus
) {
//
TODO
Auto-generated constructor stub
this
.
cus
=
cus
;
}
@Override
public
void
run() {
//
TODO
Auto-generated method stub
while
(
true
) {
try
{
Thread. sleep(100);
cus
.customerResource();
}
catch
(InterruptedException
e
) {
//
TODO
Auto-generated catch block
e
.printStackTrace();
}
}
}
}
class
Resource {
private
int
count
=0;
private
boolean
flag
=
false
;
/**
* 写法一:只通过lock和flag,控制好逻辑判断,来实现线程安全
* 逻辑判断:当有可操作数据时,才执行响应的逻辑操作,否则直接解锁释放执行权
public
void
produceResource() {
lock
.lock();
try
{
System.
out
.println(
"********************生产者抢到cpu"
);
while
(!
flag
) {
//没有数据,则启动生产者
System.
out
.println(
"********************生产者未检测到有可消费的数据,开始生产数据"
);
count
++;
System.
out
.println(Thread. currentThread().getName() +
" 生产者 ---->"
+
count
);
flag
=
true
;
}
System.
out
.println(
"********************数据已生产,等待消费者消费"
);
}
finally
{
lock
.unlock();
System.
out
.println();
}
}
public
void
customerResource() {
lock
.lock();
try
{
System.
out
.println(
"消费者抢到cpu"
);
while
(
flag
) {
//若有数据,启动消费者
System.
out
.println(
"消费者检测到资源,开始消费数据。。。。。。。。"
);
System.
out
.println(Thread. currentThread().getName() +
" 消费者 -----------> "
+
count
);
flag
=
false
;
}
System.
out
.println(
"未检测到可供消费的数据,等待生产者生产数据"
);
}
finally
{
lock
.unlock();
System.
out
.println();
}
/**
* 写法2;通过lock和condition实现线程安全
* 逻辑判断:如果没有可操作的数据,则挂起该线程,并释放CPU执行权
* 如果使用condition.singal()方法,可能会导致死锁
*
@throws
InterruptedException
/* public void produceResource() throws InterruptedException {
lock.lock();
try {
while(flag) //没有数据,则挂起该线程,并释放执行权
condition.await();
count++;
System.out.println(Thread.currentThread().getName() + " 生产者 ---->" + count);
flag = true;
condition.signalAll();;
} finally {
lock.unlock();
}
}
public void customerResource() throws InterruptedException {
lock.lock();
try {
while(!flag) //若没有数据,则挂起该消费者线程,并释放执行权
condition.await();
System.out.println(Thread.currentThread().getName() + " 消费者 -----------> " + count);
flag = false;
condition.signalAll();
} finally {
lock.unlock();
}