Java 如何使对象对所有线程可见和可编辑?
我编写了以下代码,这是阻塞队列的一个实现:Java 如何使对象对所有线程可见和可编辑?,java,multithreading,blockingqueue,Java,Multithreading,Blockingqueue,我编写了以下代码,这是阻塞队列的一个实现: public class MyBlockingQueue extends Thread{ final private List <Integer> queue; public MyBlockingQueue(){ queue = new LinkedList<Integer>(); } public synchronized int size () { return qu
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);
}
公共类MyBlockingQueue扩展线程{
最终私有列表队列;
公共MyBlockingQueue(){
队列=新的LinkedList();
}
公共同步整数大小(){
返回queue.size();
}
公共同步的void排队(int num)
抛出中断异常{
this.queue.add(num);
System.out.println(getName()+“”+num+“添加”);
通知();
}
公共同步int-dequeue()
抛出中断异常{
while(queue.size()==0)
等待();
返回此.queue.remove(0);
}
1.我尝试创建两个线程,并强制它们向队列中添加一些数字,然后将其删除。不幸的是,似乎每个线程都有自己的对象。我如何更改代码,以便两个线程处理相同的对象,并同步向同一阻塞队列添加/删除
2.我是否正确地编写了dequeue函数(这样,当一个线程从队列中删除最后一个数字并且队列大小现在为零时,其他线程将等待,直到enqueue通知它们)
这是我的测试仪:
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();
}
}
公共类主{
//检查阻塞队列
公共静态void main(字符串[]args)引发InterruptedException{
最终MyBlockingQueue mine=新MyBlockingQueue();
线程t1=新线程(){
公开募捐{
试一试{
mine.enqueue((int)(Math.random()*1000));
System.out.println(getName()+“您需要使队列保持静态,或在初始化时将对象传递给线程。如果不这样做,两个线程将在单独的队列上排队/出列。例如:
public class MyBlockingQueue extends Thread {
final private static List<Integer> queue = new LinkedList<Integer>();
public synchronized int size() {
return MyBlockingQueue.queue.size();
}
public synchronized void enqueue(int num) throws InterruptedException {
MyBlockingQueue.queue.add(num);
System.out.println(getName() + " enqueued " + num);
notify();
}
public synchronized int dequeue() throws InterruptedException {
while (MyBlockingQueue.queue.size() == 0) {
wait();
}
System.out.println(getName() + " dequeued " + MyBlockingQueue.queue.get(0));
return MyBlockingQueue.queue.remove(0);
}
}
公共类MyBlockingQueue扩展线程{
最终私有静态列表队列=新建LinkedList();
公共同步整数大小(){
返回MyBlockingQueue.queue.size();
}
公共同步的void队列(int num)抛出InterruptedException{
MyBlockingQueue.queue.add(num);
System.out.println(getName()+“排队”+num);
通知();
}
public synchronized int dequeue()引发InterruptedException{
while(MyBlockingQueue.queue.size()=0){
等待();
}
System.out.println(getName()+“dequeued”+MyBlockingQueue.queue.get(0));
返回MyBlockingQueue.queue.remove(0);
}
}
我应该转向静态的什么-列表还是阻塞队列?@Limmen在MyBlockingQueue类中准确地写出了静态队列。哦,对不起,队列是我的列表。我没有注意到。谢谢!@adi,一个对象(例如,列表
或MyBlockingQueue
)不能是静态的
。只有变量可以是静态的。@Limmen告诉您在静态变量中存储对MyBlockingQueue
对象的引用,然后为使用该变量的线程编写代码。为什么扩展线程
?队列不是一种线程。Re,“似乎每个线程都有自己的对象。如何更改代码,使两个线程都能处理同一个对象?“您没有向我们显示任何使用您的MyBlockingQueue
类的代码,因此很难说该代码有什么问题。抱歉,我附加了一个测试代码。请向我们显示打印结果。从我所看到的情况来看,您的代码是正确的。(你应该删除扩展线程,而出列函数有一个问题,但所有这些在你的测试用例上仍然有效)我已经附加了它。我想我已经成功地用其他方式管理了它,但是谢谢你!!顺便问一下,你的代码管理问题吗“当一个线程从队列中删除最后一个数字,而队列大小现在为零时,其他线程将等待队列通知它们“?它不是我的,它只是您的代码,建议进行上述修改。您可以在下一个文件的源代码中找到好的和正确的示例:ArrayBlockingQueue DelayQueue LinkedBlockingQueue Priority BlockingQueue SynchronousQueue。在java.util.concurrent Packages中,大小应为()函数是否要同步?如果要同步,如何在不写入syncronized关键字的情况下使其同步?请注意,正如james large所写的“队列不是一种线程”。您不能同步大小()并使用AtomicInteger count变量来持久化大小
public class MyBlockingQueue extends Thread {
final private static List<Integer> queue = new LinkedList<Integer>();
public synchronized int size() {
return MyBlockingQueue.queue.size();
}
public synchronized void enqueue(int num) throws InterruptedException {
MyBlockingQueue.queue.add(num);
System.out.println(getName() + " enqueued " + num);
notify();
}
public synchronized int dequeue() throws InterruptedException {
while (MyBlockingQueue.queue.size() == 0) {
wait();
}
System.out.println(getName() + " dequeued " + MyBlockingQueue.queue.get(0));
return MyBlockingQueue.queue.remove(0);
}
}