public class Lock_and_Condition
{
public static void main(String[] args)
{
Resouce re = new Resouce(); Lock lock = new ReentrantLock(); ShengChanZhe i = new ShengChanZhe(re, (ReentrantLock)lock);
XiaoFeiZhe o = new XiaoFeiZhe(re ,(ReentrantLock)lock); Thread t1 = new Thread(i, "生产者1");
Thread t2 = new Thread(i, "生产者2");
Thread t3 = new Thread(i, "生产者3");
Thread t4 = new Thread(o, "消费者1");
Thread t5 = new Thread(o, "消费者2");
Thread t6 = new Thread(o, "消费者3"); t1.start();
t2.start();
t3.start();
t4.start();
t5.start();
t6.start();
}
}class Resouce
{
private String name;
private int count = 1;
private boolean flag; public void setName(String name) {
this.name = name;
} public void setCount(int count) {
this.count = count;
} public void setFlag(boolean flag) {
this.flag = flag;
} public String getName() {
return name;
} public int getCount() {
return count;
} public boolean getFlag()
{
return flag;
}
}class XiaoFeiZhe implements Runnable
{
private Resouce res;
private Lock lock;
private Condition con;
XiaoFeiZhe(Resouce re, ReentrantLock lock)
{
this.res = re;
this.lock = lock;
con = this.lock.newCondition();
}
public void run()
{ while(true)
{
lock.lock(); //上锁,同步
//为了执行finally语句的内容,使用try
try
{
if(res.getFlag())
{
System.out.println(Thread.currentThread().getName()+"-----买走了第"+res.getCount()+"个"+res.getName());
res.setCount(res.getCount()+1);
res.setFlag(false);
con.signalAll(); //唤醒所有等待线程,赋予执行资格
}
else
{
try {
con.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
finally {
lock.unlock();
//con.signalAll(); //唤醒所有等待线程,赋予执行资格
}
}
}
}class ShengChanZhe implements Runnable
{
private Resouce re;
private Lock lock;
private Condition con;
ShengChanZhe(Resouce re, ReentrantLock lock)
{
this.re = re;
this.lock = lock;
con = this.lock.newCondition();
}
public void run()
{ while(true)
{
lock.lock();
try
{
if(re.getFlag())
{
try {
con.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
else
{
re.setName("混沌原核");
System.out.println(Thread.currentThread().getName()+"生产了第"+re.getCount()+"个"+re.getName());
re.setFlag(true);
con.signalAll(); //唤醒所有等待线程,赋予执行资格
}
}
finally {
lock.unlock();
}
}
}
}上面这段代码在执行后会出现无法生产无法消费的挂起现象。。求大佬解答一下哪里错了
{
public static void main(String[] args)
{
Resouce re = new Resouce(); Lock lock = new ReentrantLock(); ShengChanZhe i = new ShengChanZhe(re, (ReentrantLock)lock);
XiaoFeiZhe o = new XiaoFeiZhe(re ,(ReentrantLock)lock); Thread t1 = new Thread(i, "生产者1");
Thread t2 = new Thread(i, "生产者2");
Thread t3 = new Thread(i, "生产者3");
Thread t4 = new Thread(o, "消费者1");
Thread t5 = new Thread(o, "消费者2");
Thread t6 = new Thread(o, "消费者3"); t1.start();
t2.start();
t3.start();
t4.start();
t5.start();
t6.start();
}
}class Resouce
{
private String name;
private int count = 1;
private boolean flag; public void setName(String name) {
this.name = name;
} public void setCount(int count) {
this.count = count;
} public void setFlag(boolean flag) {
this.flag = flag;
} public String getName() {
return name;
} public int getCount() {
return count;
} public boolean getFlag()
{
return flag;
}
}class XiaoFeiZhe implements Runnable
{
private Resouce res;
private Lock lock;
private Condition con;
XiaoFeiZhe(Resouce re, ReentrantLock lock)
{
this.res = re;
this.lock = lock;
con = this.lock.newCondition();
}
public void run()
{ while(true)
{
lock.lock(); //上锁,同步
//为了执行finally语句的内容,使用try
try
{
if(res.getFlag())
{
System.out.println(Thread.currentThread().getName()+"-----买走了第"+res.getCount()+"个"+res.getName());
res.setCount(res.getCount()+1);
res.setFlag(false);
con.signalAll(); //唤醒所有等待线程,赋予执行资格
}
else
{
try {
con.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
finally {
lock.unlock();
//con.signalAll(); //唤醒所有等待线程,赋予执行资格
}
}
}
}class ShengChanZhe implements Runnable
{
private Resouce re;
private Lock lock;
private Condition con;
ShengChanZhe(Resouce re, ReentrantLock lock)
{
this.re = re;
this.lock = lock;
con = this.lock.newCondition();
}
public void run()
{ while(true)
{
lock.lock();
try
{
if(re.getFlag())
{
try {
con.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
else
{
re.setName("混沌原核");
System.out.println(Thread.currentThread().getName()+"生产了第"+re.getCount()+"个"+re.getName());
re.setFlag(true);
con.signalAll(); //唤醒所有等待线程,赋予执行资格
}
}
finally {
lock.unlock();
}
}
}
}上面这段代码在执行后会出现无法生产无法消费的挂起现象。。求大佬解答一下哪里错了
解决方案 »
- Java基础题
- 如何判断char里的内容
- 用Java编写文本编辑器遇到的问题,请高手赐教~!
- 谁帮我解释一下
- javamail收到邮件后,如何查看邮件的原始信息.
- 数据库连接问题
- 给位老大,求助一个AWT的初级编程:
- 关于java applet的问题
- java2核心技术卷一:原理 有好几版,不知道哪一版最好啊????
- 在简体Windows Advanced 2000下安装SQL Server 2000后,控制面板上没有ODBC DATE SOURCE,请问如何设置在JAVA中数据庫連接?
- eclipse中显示GregorianCalendar类中没有定义get方法
- eclipse怎么用快捷键看对象指向的地址
你先上锁在判断flag,这里明显有问题啊,因为经常都是抢占的,如果消费者抢了生产者的锁就会无限等待下去了。你这里明显应该先判断该生产者还是消费者,也就是先判断flag,然后再3个生产者来抢锁或3个消费者来抢锁。
帮你修改了一下import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;public class Lock_and_Condition
{
public static void main(String[] args)
{
Resouce re = new Resouce(); Lock lock = new ReentrantLock(); ShengChanZhe i = new ShengChanZhe(re, (ReentrantLock)lock);
XiaoFeiZhe o = new XiaoFeiZhe(re ,(ReentrantLock)lock); Thread t1 = new Thread(i, "生产者1");
Thread t2 = new Thread(i, "生产者2");
Thread t3 = new Thread(i, "生产者3");
Thread t4 = new Thread(o, "消费者1");
Thread t5 = new Thread(o, "消费者2");
Thread t6 = new Thread(o, "消费者3"); t1.start();
t2.start();
t3.start();
t4.start();
t5.start();
t6.start();
}
}class Resouce
{
private String name;
private int count = 1;
private boolean flag; public void setName(String name) {
this.name = name;
} public void setCount(int count) {
this.count = count;
} public void setFlag(boolean flag) {
this.flag = flag;
} public String getName() {
return name;
} public int getCount() {
return count;
} public boolean getFlag()
{
return flag;
}
}class XiaoFeiZhe implements Runnable
{
private Resouce res;
private Lock lock;
private Condition con;
XiaoFeiZhe(Resouce re, ReentrantLock lock)
{
this.res = re;
this.lock = lock;
con = this.lock.newCondition();
}
public void run()
{ while(true)
{
lock.lock(); //上锁,同步
//为了执行finally语句的内容,使用try
try
{
if(res.getFlag())
{
System.out.println(Thread.currentThread().getName()+"-----买走了第"+res.getCount()+"个"+res.getName());
res.setCount(res.getCount()+1);
res.setFlag(false);
con.signalAll(); //唤醒所有等待线程,赋予执行资格
lock.unlock();
}
else
{
try {
lock.unlock();
con.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}catch(Exception e) {
}
}
}
}class ShengChanZhe implements Runnable
{
private Resouce re;
private Lock lock;
private Condition con;
ShengChanZhe(Resouce re, ReentrantLock lock)
{
this.re = re;
this.lock = lock;
con = this.lock.newCondition();
}
public void run()
{ while(true)
{
lock.lock();
try
{
if(re.getFlag())
{
try {
lock.unlock();
con.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
else
{
re.setName("混沌原核");
System.out.println(Thread.currentThread().getName()+"生产了第"+re.getCount()+"个"+re.getName());
re.setFlag(true);
con.signalAll();
//唤醒所有等待线程,赋予执行资格
lock.unlock();
}
}catch(Exception e){
}
}
}
}
帮你修改了一下import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;public class Lock_and_Condition
{
public static void main(String[] args)
{
Resouce re = new Resouce(); Lock lock = new ReentrantLock(); ShengChanZhe i = new ShengChanZhe(re, (ReentrantLock)lock);
XiaoFeiZhe o = new XiaoFeiZhe(re ,(ReentrantLock)lock); Thread t1 = new Thread(i, "生产者1");
Thread t2 = new Thread(i, "生产者2");
Thread t3 = new Thread(i, "生产者3");
Thread t4 = new Thread(o, "消费者1");
Thread t5 = new Thread(o, "消费者2");
Thread t6 = new Thread(o, "消费者3"); t1.start();
t2.start();
t3.start();
t4.start();
t5.start();
t6.start();
}
}class Resouce
{
private String name;
private int count = 1;
private boolean flag; public void setName(String name) {
this.name = name;
} public void setCount(int count) {
this.count = count;
} public void setFlag(boolean flag) {
this.flag = flag;
} public String getName() {
return name;
} public int getCount() {
return count;
} public boolean getFlag()
{
return flag;
}
}class XiaoFeiZhe implements Runnable
{
private Resouce res;
private Lock lock;
private Condition con;
XiaoFeiZhe(Resouce re, ReentrantLock lock)
{
this.res = re;
this.lock = lock;
con = this.lock.newCondition();
}
public void run()
{ while(true)
{
lock.lock(); //上锁,同步
//为了执行finally语句的内容,使用try
try
{
if(res.getFlag())
{
System.out.println(Thread.currentThread().getName()+"-----买走了第"+res.getCount()+"个"+res.getName());
res.setCount(res.getCount()+1);
res.setFlag(false);
con.signalAll(); //唤醒所有等待线程,赋予执行资格
lock.unlock();
}
else
{
try {
lock.unlock();
con.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}catch(Exception e) {
}
}
}
}class ShengChanZhe implements Runnable
{
private Resouce re;
private Lock lock;
private Condition con;
ShengChanZhe(Resouce re, ReentrantLock lock)
{
this.re = re;
this.lock = lock;
con = this.lock.newCondition();
}
public void run()
{ while(true)
{
lock.lock();
try
{
if(re.getFlag())
{
try {
lock.unlock();
con.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
else
{
re.setName("混沌原核");
System.out.println(Thread.currentThread().getName()+"生产了第"+re.getCount()+"个"+re.getName());
re.setFlag(true);
con.signalAll();
//唤醒所有等待线程,赋予执行资格
lock.unlock();
}
}catch(Exception e){
}
}
}
}
感谢大佬,那我这样理解可以吗:await是放弃了执行资格,unlock是让出了执行权(锁),如果await先执行的话就会出现没有执行资格,但却一直占用执行权(锁),从而导致其它线程无法执行的情况?
当然可以使用不同的Condition对象实例,但前提是要互相持有对方的实例引用。否则你如何做到生产者生产好了通知消费者进行消费呢?生产者和消费者Condition对象分开的好处还在于可以进行精确的通知控制(如消费者仅唤醒生产者),
你现在的代码消费者线程中只能唤醒消费者,生产者同理