先说一下要干什么。
建一个队列,再搞五个线程从队列里面取数。队列里面有值则返回队列首元素打印一下,并结束当前线程,没有则等待。
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();
}
Sign in to make a reply
Loading...
先说一下要干什么。
建一个队列,再搞五个线程从队列里面取数。队列里面有值则返回队列首元素打印一下,并结束当前线程,没有则等待。
其中addTask的时候为什么也要加锁,大家可以试一下.还有廖大写得一些额外得代码还没get是设么意思。
add.join();
Thread.sleep(100);
for (var t : ts) {
t.interrupt();
}