我无法理解为什么我在这个简单的样本中遇到了死锁。它出了什么问题?
public static void main(String[] args) {
Object data = null;
new Thread(new Producer(data)).start();
new Thread(new Consumer(data)).start();
}
}
class Producer implements Runnable {
private Object data;
public Producer(Object data) {
this.data = data;
}
@Override
public void run() {
while (true) {
while (data != null) {}
data = new Object();
System.out.println("put");
}
}
}
class Consumer implements Runnable {
private Object data;
public Consumer(Object data) {
this.data = data;
}
@Override
public void run() {
while (true) {
while (data == null) { }
data = null;
System.out.println("get");
}
}
答案 0 :(得分:3)
有两个问题。
1:您有两个独立的Runnable,每个Runnable都有自己的私有内部成员,名为data。对一个进行的更改对另一个不可见。如果要在两个线程之间传递数据,则需要将它存储在一个共同的位置,在这两个线程中它们都可以访问它。您还需要围绕访问进行同步或使引用变为volatile。
2:你的支票似乎倒了。你可能想要在它不为空时将其置空,并在它为空时创建一个?很难说出你想要它实际在那里做什么! :)
public static volatile Object data;
public static void main(String[] args) {
data = null;
new Thread(new Producer(data)).start();
new Thread(new Consumer(data)).start();
}
}
class Producer implements Runnable {
public Producer(Object data) {
this.data = data;
}
@Override
public void run() {
while (true) {
while (data == null) {}
data = new Object();
System.out.println("put");
}
}
}
class Consumer implements Runnable {
public Consumer(Object data) {
this.data = data;
}
@Override
public void run() {
while (true) {
while (data != null) { }
data = null;
System.out.println("get");
}
}
(这也不是一个典型的例子我们定义为死锁,其中两个线程无法继续,因为它们都想要另一个拥有的锁。这里没有锁。这是两个例子无限循环,什么都不做。)
答案 1 :(得分:2)
每个实例都有自己的data
字段
消费者永远不会看到生产者的变化。
答案 2 :(得分:2)
消费者和生产者具有单独的数据字段,因此消费者永远不会获得任何数据。
此外,在字段上对消费者/制作人进行自动锁定通常不是一个好主意,您 更好地使用互斥锁或信号量来表示可用性数据/发布的可能性。如果这不仅仅是搜索知识的测试,那么你应该真正了解如何使用这两者。
答案 3 :(得分:1)
当你制作"产生"时,它所做的只是指向它自己data
对新对象的引用,而消费者无法知道发生了什么。你可以做的是做另一个班级
class Data {
private Object data = null;
synchronized void set( Object data ){ this.data = data; }
synchronized Object get(){ return data; }
}
然后在你的主要做
Data data = new Data();
传递'数据'反对消费者和生产者,并使用get / set方法而不是赋值。
这样,消费者和生产者都将指向相同的Data
对象,当生产者生产或消费者消费时,他们将改变他们共享的Data对象中的引用。
答案 4 :(得分:1)
我认为这应该做你想要的(它仍然是错误的代码):
public class Example {
public static void main(String[] args) {
Consumer consumer = new Consumer();
new Thread(new Producer(consumer)).start();
new Thread(consumer).start();
}
}
class Producer implements Runnable {
private final Consumer consumer;
public Producer(Consumer consumer) {
this.consumer = consumer;
}
@Override
public void run() {
while (true) {
while (consumer.data != null) {}
consumer.data = new Object();
System.out.println("put");
try {
Thread.sleep(5);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
class Consumer implements Runnable {
public volatile Object data;
@Override
public void run() {
while (true) {
while (data == null) {}
data = null;
System.out.println("get");
try {
Thread.sleep(5);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
我认为在开始使用并行编程等高级主题之前,您应该关注Java的基础知识,因为您的示例中的主要错误(单独的数据字段)非常基础。