Java中线程无法访问可共享资源
我无法理解为什么 Consumers 中的共享列表始终为空,而 Provider 却向其中添加值。 我有提供者:
class Provider extends Thread {
List<Integer> products;
Random rnd = new Random();
public Provider(List<Integer> products) {
this.products = products;
}
@Override
public void run() {
//Provider just generate random value and adds the value to the shared list
for (int i = 0; i < 10; i++) {
Integer product = rnd.nextInt(100);
System.out.println("added value: "+product);
products.add(product);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
和消费者:
class Consumer extends Thread {
List<Integer> products;
public Consumer(List<Integer> products) {
this.products = products;
}
@Override
public void run() {
System.out.println("Consumer started");
for (int i = 0; i < 5;) {
//Consumer just removes elements from shared list five times
if (!products.isEmpty()) {
Integer product = products.remove(0);
System.out.println("removed: "+product);
i++;
}
}
System.out.println("Consumer stopped");
}
}
主要有以下内容:
List<Integer> products = new ArrayList<>();
new Provider(products).start();
new Consumer(products).start();
new Consumer(products).start();
我认为每个消费者在提供者向可共享列表添加值后应该从可共享列表中读取五个值,但在消费者中列表始终为空。为什么列表不更新?
我得到以下结果:
Consumer started
Consumer started
added value: 13
removed: 13
removed: 13
added value: 28
added value: 53
added value: 32
added value: 85
added value: 23
added value: 60
added value: 10
added value: 15
added value: 85
提供者完成后,消费者正在工作,但由于这种情况无法删除任何项目。
请不要写同步。我知道线程应该同步对公共资源的访问。但这是研究示例,我的目标是让消费者阅读并从列表中删除值。
I can't get to understand why the shared list in Consumers is always empty while the Provider adds values to it.
I have the Provider:
class Provider extends Thread {
List<Integer> products;
Random rnd = new Random();
public Provider(List<Integer> products) {
this.products = products;
}
@Override
public void run() {
//Provider just generate random value and adds the value to the shared list
for (int i = 0; i < 10; i++) {
Integer product = rnd.nextInt(100);
System.out.println("added value: "+product);
products.add(product);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
And the the Consumer:
class Consumer extends Thread {
List<Integer> products;
public Consumer(List<Integer> products) {
this.products = products;
}
@Override
public void run() {
System.out.println("Consumer started");
for (int i = 0; i < 5;) {
//Consumer just removes elements from shared list five times
if (!products.isEmpty()) {
Integer product = products.remove(0);
System.out.println("removed: "+product);
i++;
}
}
System.out.println("Consumer stopped");
}
}
In the main I have the following:
List<Integer> products = new ArrayList<>();
new Provider(products).start();
new Consumer(products).start();
new Consumer(products).start();
I supposed each Consumer should read five values from shareable list after the Provider adds values to it, but in the Consumers the list is always empty. Why the list isn't being updated?
I get the following result:
Consumer started
Consumer started
added value: 13
removed: 13
removed: 13
added value: 28
added value: 53
added value: 32
added value: 85
added value: 23
added value: 60
added value: 10
added value: 15
added value: 85
After the Provider has finished the Consumers are working but can't remove any item because of the condition.
Please don't write about synchronisation. I understand that the threads should synchronize the access to common resource. But it's study example and my goal is to make the Consumers read and remove the values from list.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
我认为第一条评论击中要害。如果没有任何同步,则不能保证线程看到更新。尤其是像这样的紧密循环。
添加同步到消费者对我来说很有效。
当我在没有同步的情况下尝试此操作时,消费者永远不会从列表中获取。
I think the first comment hits the nail on the head. Without any synchronization then the threads are not guaranteed to see an update. Especially with a tight loop like that.
Adding synchronized to the consumer works for me.
When I tried this without synchronization the consumers never take from the list.