Я написал этот код, орудие блокировки очереди:Как сделать объект видимым и редактируемым для всех потоков?
public class MyBlockingQueue extends Thread{
final private List <Integer> queue;
public MyBlockingQueue(){
queue = new LinkedList<Integer>();
}
public synchronized int size() {
return queue.size();
}
public synchronized void enqueue(int num)
throws InterruptedException {
this.queue.add(num);
System.out.println(getName()+" "+num+" added");
notify();
}
public synchronized int dequeue()
throws InterruptedException{
while(queue.size() == 0)
wait();
return this.queue.remove(0);
}
1.я попытался сделать два потока и заставить их добавить некоторое количество в очереди, а затем удалить его. Unfortunatley, похоже, что у каждой нити есть свой объект. как я могу изменить код, чтобы оба потока обрабатывали один и тот же объект и добавляли/удаляли в ту же очередь блокировки синхронно?
2. Я правильно записываю функцию dequeue (так что, когда один поток удаляет последний номер из очереди, а размер очереди равен нулю, другие потоки будут ждать, пока очередь будет уведомлять их)?
это мой тестер:
public class Main {
//checks the blocking queue
public static void main(String[] args) throws InterruptedException {
final MyBlockingQueue mine = new MyBlockingQueue();
Thread t1 = new Thread(){
public void run(){
try {
mine.enqueue((int)(Math.random()*1000));
System.out.println(getName()+"<- enter");
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
};
}
};
Thread t2 = new Thread(){
public void run(){
try {
mine.dequeue();
System.out.println(getName()+"<-remove");
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
};
Thread t3 = new Thread(){
public void run(){
try {
mine.dequeue();
System.out.println(getName()+"<-remove");
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
};
Thread t4 = new Thread(){
public void run(){
try {
mine.enqueue((int)(Math.random()*1000));
System.out.println(getName()+"<-enter");
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
};
Thread t5 = new Thread(){
public void run(){
try {
mine.dequeue();
System.out.println(getName()+"<-remove");
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
};
Thread t6 = new Thread(){
public void run(){
System.out.println("thread 6 of entering began, should release last thread of remove");
try {
mine.enqueue((int)(Math.random()*1000));
System.out.println(getName()+"<-enter");
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
};
Thread t7 = new Thread(){
public void run(){
try {
mine.dequeue();
System.out.println(getName()+"<-remove");
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
};
Thread t8 = new Thread(){
public void run(){
try {
mine.dequeue();
System.out.println(getName()+"<-remove");
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
};
Thread t9 = new Thread(){
public void run(){
try {
mine.dequeue();
System.out.println(getName()+"<-remove");
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
};
Thread t10 = new Thread(){
public void run(){
try {
mine.dequeue();
System.out.println(getName()+"<-remove");
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
};
Thread t11 = new Thread(){
public void run(){
System.out.println("thread 11 come to help, this comment before entering, after that we should see one add one remove");
try {
mine.enqueue((int)(Math.random()*1000));
System.out.println(getName()+"<-enter");
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
};
t1.start();
t2.start();
t3.start();
Thread.sleep(5000);
t4.start();//will the remove wai for the enter
Thread.sleep(5000);
/////4 tries to remove, one enter
t5.start(); //requesting to remove before have something
t7.start();
t8.start();
t9.start();
t10.start();
Thread.sleep(5000);
t6.start();
Thread.sleep(20000);//after 20 sec, t11 come to help
t11.start();
}
}
здесь выход:
Thread-0 enqueued 1
Thread-1<- enter
Thread-0 dequeued 1
Thread-2<-remove
Thread-0 enqueued 4
Thread-0 dequeued 4
Thread-3<-remove
Thread-4<-enter
thread 6 of entering began, should release last thread of remove
Thread-0 enqueued 6
Thread-0 dequeued 6
Thread-5<-remove
Thread-6<-enter
thread 11 come to help, this comment before entering, after that we should see one add one remove
Thread-0 enqueued 11
Thread-0 dequeued 11
Thread-8<-remove
Thread-11<-enter
Почему 'расширяет Thread'? Очередь не является ниткой. –
Re: «Кажется, что каждый поток имеет свой собственный объект. Как я могу изменить код, чтобы оба потока обрабатывали один и тот же объект?» Вы не показали нам никакого кода, который использует ваш класс MyBlockingQueue, поэтому трудно сказать, что может или не может быть ошибкой с этим кодом. –
извините, я приложил к нему тестовый код – adi