如何使对象可见并可编辑到所有线程?

时间:2016-04-25 16:43:08

标签: java multithreading blockingqueue

我编写了这段代码,阻塞队列的实现:

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.我试图创建两个线程并强制它们在队列中添加一些数字,然后将其删除。不幸的是,似乎每个线程都有自己的对象。如何更改代码,以便两个线程同时处理同一个对象并添加/删除到同一个阻塞队列?

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

}

}

这是输出:

   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

2 个答案:

答案 0 :(得分:0)

您需要使队列静态或在初始化时将对象传递给线程。如果不这样做,则两个线程将在不同的队列中进行/出列。

答案 1 :(得分:-1)

例如:

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