现在,我开始学习线程并决定编写此类以演示多线程的想法,但输出不是我想要的。
我写的课程如下: -
import java.util.LinkedList;
class QueueTest extends LinkedList{
int capacity;
LinkedList list;
public QueueTest(int capacity){
this.capacity = capacity;
list = new LinkedList();
}
public synchronized void addElements(int i)throws InterruptedException{
if(list.size() == capacity ){
wait();
}
add(i);
System.out.println("I added : "+i);
notify();
}
public synchronized int getElements() throws InterruptedException{
if(!isEmpty()){
wait();
}
int i = (Integer) list.remove();
System.out.println("I got : "+i);
notify();
return i;
}
}
class Add implements Runnable{
QueueTest t ;
public Add(QueueTest t){
this.t = t;
new Thread(this,"Add").start();
}
@Override
public void run(){
int i = 0;
while(t.size() <= t.capacity){
try{
t.addElements(i++);} catch(InterruptedException e){}
}
}
}
class Remove implements Runnable{
QueueTest t ;
public Remove(QueueTest t){
this.t = t;
new Thread(this,"Remove").start();
}
@Override
public void run(){
while(!t.isEmpty()){
try{
t.getElements();} catch(InterruptedException e){}
}
}
}
public class FullQueue{
public static void main(String[] args){
QueueTest t = new QueueTest(5);
new Add(t);
new Remove(t);
}
}
我希望输出像
i added : 1
i got : 1
i added : 2
i got : 2
...等等,但是我得到了输出
I added : 0
I added : 1
I added : 2
I added : 3
I added : 4
I added : 5
,因为两个线程立即运行,因此根本无法保证或控制哪个何时或以什么顺序运行。
get可以在设置之前完全运行,设置可以完全运行,或者可以混合所有混合。
像您上面显示的那样的偶数交错不太可能发生。
在那种情况下,列表已经完全由一个线程填充,但是当空的线程在列表中没有任何内容时首先运行并退出。
添加诊断设备以显示每个线程何时启动和结束,您应该看到。结果每次运行都会有所不同。
目前您的notify
无需执行任何操作,因为您什么都没有等待。要使线程交流,然后每次写入或阅读后都应通知然后等待。但是,您需要同步整个块,从本质上讲,您最终以一种非常复杂的方法来获得与一个线程相同的结果。
这加载了种族条件。请注意,如果没有元素,则删除线程将立即退出。