Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/378.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 如何使对象对所有线程可见和可编辑?_Java_Multithreading_Blockingqueue - Fatal编程技术网

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);
    }
}