黑马程序员技术交流社区
标题:
JAVA 多线程_线程通信_Lock & Condition 问题、、、
[打印本页]
作者:
yting_xmei1129
时间:
2013-10-9 11:08
标题:
JAVA 多线程_线程通信_Lock & Condition 问题、、、
本帖最后由 yting_xmei1129 于 2013-10-12 23:42 编辑
下面是代码、、、
package yting.day11.thread;
import java.util.concurrent.locks.*;
public class LockCondition_ProducerConsumerDemo1 {
public static void main(String[] args) {
Resource_all res = new Resource_all();
//两个生产者
new Thread(new Producer_all(res)).start();
new Thread(new Producer_all(res)).start();
//两个消费者
new Thread(new Consumer_all(res)).start();
new Thread(new Consumer_all(res)).start();
}
}
class Resource_all {
private String name;
private int count = 1;
private boolean flag = false;
private Lock lock = new ReentrantLock();
private Condition cond = lock.newCondition();
public synchronized void setName(String name) {
lock.lock();
try {
while (flag) {
cond.await();
}
this.name = name + "---" + count++;
System.out.println(Thread.currentThread().getName() + "...生产者..." + this.name);
flag = true;
cond.signalAll();
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
lock.unlock();
}
}
public synchronized void print(){
lock.lock();
try {
while (!flag) {
cond.await();
}
System.out.println(Thread.currentThread().getName() + "...消费者.........." + name);
flag = false;
cond.signalAll();
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
lock.unlock();
}
}
}
class Producer_all implements Runnable {
private Resource_all r;
public Producer_all(Resource_all r) {
this.r = r;
}
@Override
public void run() {
while(true){
r.setName("商品");
}
}
}
class Consumer_all implements Runnable {
private Resource_all r;
public Consumer_all(Resource_all r) {
this.r = r;
}
@Override
public void run() {
while(true){
r.print();
}
}
}
复制代码
运行的时候会一直等在那里,求大神解答,感激不尽、、、
作者:
天下
时间:
2013-10-9 13:36
标题:
RE: JAVA 多线程_线程通信_Lock & Condition 问题、、、
/*生产者,消费者练习
jdk1.5新特性:java.util.concurrent.lock包中
接口Lock(子类 ReentrantLock) :lock(); unlock()f方法 已替代了synchronized函数和synchronized代码块
一个锁机制支持多个Condition对象
接口Condition :awit(); signal(); signalAll()方法已替代wit(); notify(); notifyAll()方法
你的代码运行全部等待问题:是因为SignalAll不仅唤醒了本方线程,而且唤醒了对方线程造成的全部等待
第一个问题:
private Condition cond_1 = lock.newCondition();
private Condition cond_2 = lock.newCondition();//建立多个condition,两组awiat()
第二个问题:
public void setName(String name) {//Lock 替代了synchronized函数[code]import java.util.concurrent.locks.*;
public class LockCondition_ProducerConsumerDemo1 {
public static void main(String[] args) {
Resource_all res = new Resource_all();
//两个生产者
new Thread(new Producer_all(res)).start();
new Thread(new Producer_all(res)).start();
//两个消费者
new Thread(new Consumer_all(res)).start();
new Thread(new Consumer_all(res)).start();
}
}
class Resource_all {
private String name;
private int count = 1;
private boolean flag = false;
private Lock lock = new ReentrantLock();
private Condition cond_1 = lock.newCondition();
private Condition cond_2 = lock.newCondition();//修改1多个condition
public void setName(String name) {//Lock 替代了synchronized函数
lock.lock();
try {
while (flag) {
cond_1.await();
}
this.name = name + "---" + count++;
System.out.println(Thread.currentThread().getName() + "...生产者..." + this.name);
flag = true;
cond_2.signal();
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
lock.unlock();
}
}
public synchronized void print(){
lock.lock();
try {
while (!flag) {
cond_2.await();
}
System.out.println(Thread.currentThread().getName() + "...消费者.........." + name);
flag = false;
cond_1.signal();
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
lock.unlock();
}
}
}
class Producer_all implements Runnable {
private Resource_all r;
public Producer_all(Resource_all r) {
this.r = r;
}
@Override
public void run() {
while(true){
r.setName("商品");
}
}
}
class Consumer_all implements Runnable {
private Resource_all r;
public Consumer_all(Resource_all r) {
this.r = r;
}
@Override
public void run() {
while(true){
r.print();
}
}
}
复制代码
[/code]
作者:
王飚
时间:
2013-10-9 13:38
我想应该是两个消费者线程都被冻结了而没有释放执行权
作者:
yting_xmei1129
时间:
2013-10-9 13:45
天下 发表于 2013-10-9 13:36
[/code]
原来只要把那个 synchronized 删除了就好了,这太不细心了、、、谢了
作者:
王飚
时间:
2013-10-9 14:18
楼主,你的程序的问题在于使用了同步:synchronized然后又使用了Lock和Condition接口,这两个接口是jdk1.5之后的版本,也让多线程同步变得更加的灵活,而你的代码中,Resource_all中使用的是同步函数,但在里面又用了Lock和Condition接口,但是synchronized只对应的是一个锁。而接口Lock和Condition可心对应多个锁,也可以唤醒指定的线程。所以,你的代码应该是出现死锁状态了,下面,我将同步和使用接口的代码分别发上来:
作者:
王飚
时间:
2013-10-9 14:27
/*
线程间通信-生产者消费者
使用同步synchronized
唤醒其它线程用notify();
*/
class ProduceConsumerDemo
{
public static void main(String[] args)
{
Resource res=new Resource();
new Thread(new Producer(res)).start();
new Thread(new Producer(res)).start();
new Thread(new Consumer(res)).start();
new Thread(new Consumer(res)).start();
}
}
class Resource
{
private String name;
private int count=1;//标记
private boolean flag=false;
//t1 t2
public synchronized/*使用同步*/ void set(String name)
{
/*if*/while(flag)//这里不能用if()因为if()只能判断一次
try{this.wait();}catch(InterruptedException e){}//t1(放弃资格) t2(获取资格)
this.name=name+"---"+count++;//加上编号赋值
System.out.println(Thread.currentThread().getName()+"produce"+this.name);
flag=true;
notifyAll();//这里省略了this.
/*
上面的notifyAll()是唤醒所有线程,而楼主的代码中是用condition.signal()唤醒,
但是注意,这是是用同步函数,所以,用notify来唤醒线程;
*/
}
//t3 t4
public synchronized void out()
{
/*if*/while(!flag)
try{this.wait();}catch(InterruptedException e){}
System.out.println(Thread.currentThread().getName()+"消费者....."+this.name);
flag=false;
notifyAll();
}
}
//
class Producer implements Runnable//生产
{
private Resource res;
Producer(Resource r)
{
this.res=r;
}
public void run()
{
while(true)
res.set("商品");
}
}
class Consumer implements Runnable//消费者
{
private Resource res;
Consumer(Resource r)
{
this.res=r;
}
public void run()
{
while (true)
{
res.out();
}
}
}
复制代码
作者:
王飚
时间:
2013-10-9 14:36
/*
线程间通信-生产者消费者_1
使用Lock和Condition接口实现多线程
*/
import java.util.concurrent.locks.*;
class ProduceConsumerDemo_1
{
public static void main(String[] args)
{
Resource res=new Resource();
new Thread(new Producer(res)).start();
new Thread(new Producer(res)).start();
new Thread(new Consumer(res)).start();
new Thread(new Consumer(res)).start();
}
}
class Resource
{
private String name;
private int count=1;//标记
private boolean flag=false;
private Lock lock=new ReentrantLock();// 返回绑定到此 Lock 实例的新 Condition 实例。
private Condition condition_pro=lock.newCondition();
private Condition condition_con=lock.newCondition();
//注意:下面就不需要同步函数synchronized
public void set(String name) throws InterruptedException
{
lock.lock();
try
{
while(flag)
condition_pro.await();
this.name=name+"---"+count++;
System.out.println(Thread.currentThread().getName()+"produce"+this.name);
flag=true;
condition_con.signal();//唤醒消费者等待线程
}
finally
{
lock.unlock();//无论是否有InterruptedException异常,都要释放锁
}
}
public void out() throws InterruptedException
{
lock.lock();
try{
while(!flag)
condition_con.await();//消费者线程冻结
System.out.println(Thread.currentThread().getName()+"消费者....."+this.name);
flag=false;
condition_pro.signal();//唤醒生产者线程
}
finally
{
lock.unlock();
}
}
}
class Producer implements Runnable
{
private Resource res;
Producer(Resource r)
{
this.res=r;
}
public void run()
{
while(true)
try
{
res.set("商品");
}
catch (InterruptedException e)
{
}
}
}
class Consumer implements Runnable
{
private Resource res;
Consumer(Resource r)
{
this.res=r;
}
public void run()
{
while (true)
{
try
{
res.out();
}
catch (InterruptedException e)
{
}
}
}
}
复制代码
作者:
yting_xmei1129
时间:
2013-10-12 23:42
王飚 发表于 2013-10-9 14:36
谢了,果然是大神也、、、
欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/)
黑马程序员IT技术论坛 X3.2