Discuss / Java / 简单说一下最后一个例子

简单说一下最后一个例子

Topic source

Loading...

#1 Created at ... [Delete] [Delete and Lock User]

先说一下要干什么。

建一个队列,再搞五个线程从队列里面取数。队列里面有值则返回队列首元素打印一下,并结束当前线程,没有则等待。

   var q = new TaskQueue();

   for (int i=0; i<5; i++) {
            var t = new Thread() {
                public void run() {
                    // 执行task:
                      try {
                            //从q的队列里面取数时,q的队列为空,五个线程全部等待
                            //(实际状态是,第一个拿到this锁的线程进入等待状态,其他线程锁都没拿到也是在等待状态)
                            //取数的时候为什么要加锁,假设没有锁,队列只有一个数,两个线程同时判断队列都不为空,两个线程
                            //要会往外取数,线程一取走这个元素后,线程二再取就会报错。保证每次操作队列的只有一个线程
                            String s = q.getTask();
                            System.out.println(s);
                        } catch (InterruptedException e) {
                            return;
                        }
                }
            };
            t.start();
        }
 //现在队列里面是没有数的,搞一个线程往q的queue里面放数。
 var add = new Thread(() -> {
                //假设先放一个数,并且唤醒等待的线程 (notifyAll) wait和notify方法都要放在sychornized代码块中
                String s = Math.random();
                q.addTask(s);//执行完addTask后等待的线程被唤醒,继续执行while循环,此时队里不为空,返回数据,释放锁.
                            //此线程结束,其他某个线程获取到this锁,判断队列是否为空,是否需要等待

                //for (int i = 0; i < 5; i++) {  //假设我们在队列中直接放五个数据每放一个则被某线程取出一个,并结束该线程,这样
                //String s =  Math.random();     //写可直接结束主程序              
                //q.addTask(s); }
        });
        add.start();



class TaskQueue {
    Queue<String> queue = new LinkedList<>();

    public synchronized void addTask(String s) {
        this.queue.add(s);
        this.notifyAll();
    }

    public synchronized String getTask() throws InterruptedException {
        while (queue.isEmpty()) {
            this.wait();
        }
        return queue.remove();
    }
}

其中addTask的时候为什么也要加锁,大家可以试一下.还有廖大写得一些额外得代码还没get是设么意思。

 add.join();

        Thread.sleep(100);

        for (var t : ts) {

            t.interrupt();

        }


  • 1

Reply