下面是代码示例:使用5或6个值后,线程被挂起
我不知道我在哪里丢失任何东西。还有一个疑问,我是关于调用MyIncrementor类的构造函数的。最初,我试图通过创建MyIncrementor类的新对象来调用Producer和Consumer类中的get和set,但它也无法正常工作
/**
*
*/
package multithreadingDemo;
/**
* @author Aquib
*
*/
public class ThreadCommDemo {
/**
* @param args
* @throws InterruptedException
*/
public static void main(String[] args) throws InterruptedException {
// TODO Auto-generated method stub
MyIncrementor mi=new MyIncrementor();
Producer1 p=new Producer1(mi);
Consumerrs c=new Consumerrs(mi);
Thread t1=new Thread(p);
Thread t2=new Thread(c);
t1.start();
t2.start();
}
}
class MyIncrementor {
int myCount;
boolean valueSet;
/**
* @return the myCount
*/
public synchronized int getMyCount() {
if (!valueSet) {
try {
wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
System.out.println("get" + myCount);
valueSet = true;
notifyAll();
return myCount;
}
/**
* @param myCount
* the myCount to set
*/
public synchronized void setMyCount(int myCount) {
if (valueSet) {
try {
wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
System.out.println("Set" + myCount);
this.myCount = myCount;
valueSet = false;
notifyAll();
}
}
class Producer1 implements Runnable {
MyIncrementor mi;
public Producer1(MyIncrementor mi) {
// TODO Auto-generated constructor stub
this.mi=mi;
}
public void run() {
for (int i = 1; i < 10; i++) {
mi.setMyCount(i);
System.out.println("Produced" + mi.myCount);
try
{
Thread.currentThread().sleep((int)(Math.random() * 100));
}
catch (InterruptedException ie)
{
ie.printStackTrace();
}
}
}
}
class Consumerrs implements Runnable {
MyIncrementor mi;
public Consumerrs(MyIncrementor mi) {
// TODO Auto-generated constructor stub
this.mi=mi;
}
public void run() {
for (int i = 1; i < 10; i++) {
int val = mi.getMyCount();
System.out.println("Consumed" + val);
}
}
}
最佳答案
您在MyIncrementor
类中只是逻辑上的错误,您在设置valueSet
时设置不正确,因此您必须更改条件或在getMyCount
和setMyCount
方法中设置反之亦然。
因此,这是MyIncrementor
的更正版本:
class MyIncrementor {
int myCount;
boolean valueSet = false; //line changed - just to show that by default it is initialized to false
/**
* @return the myCount
*/
public synchronized int getMyCount() {
while (!valueSet) { //corrected as advised in comments, see @Tom Hawtin - tackline answer for details
try {
wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
System.out.println("get" + myCount);
valueSet = false; //line changed - after getting the value set flag to false
notifyAll();
return myCount;
}
/**
* @param myCount
* the myCount to set
*/
public synchronized void setMyCount(int myCount) {
while (valueSet) { //corrected as advised in comments, see @Tom Hawtin - tackline answer for details
try {
wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
System.out.println("Set" + myCount);
this.myCount = myCount;
valueSet = true; //line changed - after setting the value set flag to true
notifyAll();
}
}