有一个产生随机整数的线程,并将它们放入一个列表中。还有两个线程同时使用列表中的项目。这些线程需要总结他们从列表中获取的项目。暂停这些线程,直到填充列表。然后打印出两个线程的总和结果。
我认为,wait()
和notify()
应该在这里使用。但是,我不确定我是否正确理解它是如何工作的。
此线程从列表中抓取项目
@Override
public void run() {
try
{
while (list.size() > 0) {
synchronized (list) {
list.wait();
result += (Integer) list.remove(0);
}
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
这就是填写清单的内容。
@Override
public void run() {
try {
synchronized (list) {
list.wait();
for (int i = 0; i < 10; i++) {
list.add(random.nextInt());
System.out.println("fill");
}
list.notify();
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
然而,他们永远不会完成。
答案 0 :(得分:1)
您的代码存在许多问题:
有证据表明存在足够的混淆,我建议在开始编写代码之前尝试以更抽象的方式思考这个问题。
答案 1 :(得分:1)
我觉得我太误解了这个问题。这是正确的解决方案。
填写清单。
@Override
public void run() {
synchronized(list) {
for (int i = 0; i < 10; i++) {
list.add(random.nextInt());
}
list.notify();
}
}
这是项目的总和。
@Override
public void run() {
synchronized(list) {
while (list.size() > 0) {
result += (Integer) list.remove(0);
}
list.notify();
}
}
所以他们只需要自己锁定列表。
这样,打印出最终解决方案:
try {
sum1.join();
sum2.join();
System.out.println(sum1.getResult() + sum2.getResult());
} catch (InterruptedException e) {
e.printStackTrace();
}
无论如何,我不认为这样实现的并发性没有任何实际用途 - 这只是一个课程任务。
答案 2 :(得分:0)
填充线程中的notify()调用仅通知其中一个等待线程。只有一个线程继续拉一个整数。然后它再次等待。没有任何解雇通知,它会永远等待。它只需等待列表中没有任何内容。
使用像这样的BlockingQueue而不是重新发明轮子:
public Runnable createSum( final BlockingQueue<Integer> queue, final BlockingQueue<Integer> output ) {
return new Runnable() {
public void run() {
Integer result = 0;
while( !queue.isEmpty() ) {
result += queue.take();
}
output.put( result );
}
}
}
public void go() {
BlockingQueue<Integer> input = new ArrayBlockingQueue<Integer>();
BlockingQueue<Integer> output = new ArrayBlockingQueue<Integer>();
Thread runner1 = new Thread( createSum( input, output ) );
Thread runner2 = new Thread( createSum( input, output ) );
for( int i = 0; i < 10; i++ ) {
input.put( random.nextInt() );
}
runner1.start();
runner2.start();
runner1.join();
runner2.join();
Integer result = 0;
while( !output.isEmpty() ) {
result += output.take();
}
System.out.println( result );
}
此解决方案仅在队列填满后才开始对事物进行求和,但在您的解决方案中它正在做同样的事情。