多线程学习之路-学习wait和notify

由于工作需要,公司项目开始转Java,大部分东西需要自学来完成,之前在网上看过好多视频教程,其中有个作业是使用 wait notify 实现一个队列,队列有2个方法,put 和 take 。put方法往队列中添加元素,take方法往队列中获得元素。
队列必须是线程安全的。如果put执行时,队列为空,线程必须阻塞等待,直到有队列有数据。如果put时,队列已经满,则put线程要等待,直到队列有空闲空间。网上找了好多答案,好多答案都是使用 ArrayBlockingQueue<Integer>实现的,
感觉都不是很符合这个题目的要求,索性自己就摸索着
写了一个例子;先说一下解题思路
1.首先定义一个普通的Java类
2.既然是队列里面必须申请一个list对应,这里我用了LinkedList实现了List接口;
3.定义了List,就需要对list有添加和移除的方法,因此产生了put和take的两个方法;put中判断长度,大于定义长度则wait;小于则添加并且notify其他线程;take操作类似;
4.多线程操作,肯定需要一个对象锁,因此声明了类型为Object的lock锁;
5.作为设置了List最大长度,因此申明了AtomicInteger的count对象,此时为啥不用list.size()获取长度,因为多线程的操作size没有同步功能;
大概思路就是这样,下面直接上代码,代码可以直接运行的;内容是根据网络视频写的,欢迎大家转载学习交流;
 1 package threadtest;
 2 
 3 import java.util.LinkedList;
 4 import java.util.concurrent.TimeUnit;
 5 import java.util.concurrent.atomic.AtomicInteger;
 6 
 7 public class QueueTest01 {
 8     private LinkedList<Object> list = new LinkedList<Object>();
 9     private AtomicInteger count = new AtomicInteger(0);
10     private final int minSize = 0;
11     private final int maxSize;
12 
13     public QueueTest01(int maxsize) {
14         this.maxSize = maxsize;
15     }
16 
17     private final Object lock = new Object();
18 
19     public void put(Object obj) {
20         synchronized (lock) {
21             while (this.maxSize == count.get()) {
22                 try {
23                     lock.wait();
24                 } catch (InterruptedException e) {
25                     // TODO Auto-generated catch block
26                     e.printStackTrace();
27                 }
28             }
29             list.add(obj);
30             count.incrementAndGet();
31             System.out.println("新加入的元素是:" + obj);
32             lock.notify();
33         }
34     }
35 
36     public Object take() {
37         Object obj = null;
38         synchronized (lock) {
39             while (this.minSize == count.get()) {
40                 try {
41                     lock.wait();
42                 } catch (InterruptedException e) {
43                     // TODO Auto-generated catch block
44                     e.printStackTrace();
45                 }
46             }
47             obj = list.removeFirst();
48             count.decrementAndGet();
49             lock.notify();
50         }
51         return obj;
52     }
53 
54     public static void main(String[] args) {
55         final QueueTest01 myQueue = new QueueTest01(5);
56         myQueue.put("a");
57         myQueue.put("b");
58         myQueue.put("c");
59         myQueue.put("d");
60         myQueue.put("e");
61         System.out.println("当前对列的长度:" + myQueue.list.size());
62 
63         Thread t1 = new Thread(new Runnable() {
64 
65             @Override
66             public void run() {
67                 myQueue.put("f");
68                 myQueue.put("g");
69             }
70         }, "t1");
71         t1.start();
72         Thread t2 = new Thread(new Runnable() {
73 
74             @Override
75             public void run() {
76                 Object o1 = myQueue.take();
77                 System.out.println("移除的元素为:" + o1);
78                 Object o2 = myQueue.take();
79                 System.out.println("移除的元素为:" + o2);
80             }
81         }, "t2");
82         try {
83             TimeUnit.SECONDS.sleep(2);
84         } catch (InterruptedException e) {
85             // TODO Auto-generated catch block
86             e.printStackTrace();
87         }
88         t2.start();
89 
90     }
91 }

 

posted @ 2017-08-23 23:12  蜗牛超悍马  阅读(168)  评论(0编辑  收藏  举报