当前位置: 首页 > 知识库问答 >
问题:

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

曹新觉
2023-03-14

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

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.我是否正确地编写了出队列函数(这样,当一个线程从队列中删除最后一个数字并且队列大小现在为零时,其他线程将等待队列通知它们)?

这是我的测试器:

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个答案

淳于枫
2023-03-14

例如:

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);
    }
}
公西马鲁
2023-03-14

您需要使队列成为静态的,或者在初始化时将对象传递给线程。如果不这样做,两个线程将在单独的队列上排队/取消排队。

 类似资料:
  • 问题内容: 有没有办法使某些CSS规则仅对Opera(9.5 +)可见? 问题答案: 此技巧适用于最新的Opera: 据我测试,它并没有碰到任何其他浏览器,但是随着网络技术的繁荣等,这可能会持续几个月。

  • 问题内容: 你好。我有一个实现runnable的类,并且有一个List,用于存储用该类的不同对象实例化的线程。给定运行线程对象的基础对象,如何访问基础对象的属性?这是一个例子: 问题答案: 我在文档中看不到任何方法。 那么,我最好的答案是您可能应该使用而不是(或在之上)使用。或者,也许您想要某种映射结构,以便可以从线程访问Runnable。(例如,)

  • 是否可以使用iTextSharp从PDF文档中删除不可见(或至少不显示)的对象? 更多详情: 这种解决方案有2个大缺点: 文档的大小是[原始大小]*[裁剪框的数量],因为整个页面都在那里,盖了很多次戳!(看不见,但它在那里) 仍然可以通过在Reader中选择all(Ctrl+A)并粘贴来访问不可见文本。 所以,我想我需要迭代PDF对象,检测它是否可见,并删除它。在撰写本文时,我正在尝试使用pdfr

  • 问题内容: 我的本地Windows设备上有一个Jenkins服务器,但我想使它对外界不可见(关于服务器的办公规则)。一种令人满意的工作方式是显而易见的,微妙的方法,它是设置防火墙规则以阻止对其端口的传入访问,但是我认为必须有一个Jenkins设置来阻止它向除本地主机之外的任何人发布其服务。谁能告诉我是否有? 请注意,设置用户凭据不是有效的解决方案,因为服务器可见但未经登录便无法访问,这仍然违反了办

  • 问题内容: 有以下课程: } 它产生以下结果: 由于hashCode取决于对象的状态,因此无法再正确检索它,因此对包含的检查失败。HashSet不再正常工作。一个解决方案是使Member不可变,但这是唯一的解决方案吗?是否所有添加到HashSets的类都是不可变的?还有其他方法可以处理这种情况吗? 问候。 问题答案: 在hashsets对象应该 要么 是不可变的, 或者 你需要锻炼的纪律,他们已经

  • 所以我有下面的代码,用Kotlin写的。 我在最后一条指令行()上得到一个编译错误,编译器说,但我不知道为什么。 我认为同伴对象应该对它们“陪伴”的类的属性具有某种可见性。 (免责声明:此代码正在从Java迁移到Kotlin。在Java版本上,以前是同一个类上的静态方法。) 多谢!