近期,公司环境很不稳定,之前招我的元老级别的人物都陆陆续续的离开了公司。里头的那些弯弯绕绕也就不跟大家吐槽了,我还是静静的做好手边的事情,yuanlai闲着无事整理了线程这块的东西。最让我,感觉神奇的就是线程之间的通信。在实现的发现真的是代码如人生。
1.使用wait、notify方法实现线程间的通信
2.wait和notify必须配合synchronized关键字使用
3.wait方法释放锁,notify方法不释放锁。
4.wait和notify必须配合synchronized一起使用
说明:有个场景就是在一个容器中,容器最大是装入5个元素,当他有空间的时候,执行put操作,当他没有空间的时候执行take操作。
这个就需要两个线程,一个线程在有空间的时候就put,一个线程在空间满了的时候就执行take操作。
package com.example.profile;
import java.util.LinkedList;
import java.util.concurrent.atomic.AtomicInteger;
//说明:使用组赛队列实现当队列未满的时候向里头加入元素,队列里头有元素的时候取出元素
public class Myqueue {
//1.需要一个集合
private final LinkedList<Object> list = new LinkedList();
//2.计数器统计
private AtomicInteger count = new AtomicInteger(0);
//3.需要定制上限和下限
private final Integer minSize=0;
private final Integer maxSize;
//4.构造方法
public Myqueue(Integer size){
this.maxSize=size;
}
//5.初始化一个对象并且枷锁
private final Object lock = new Object();
//6.put一个对象
public void put(Object object){
synchronized (lock){
while(this.maxSize==count.get()){
try {
lock.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("队列已经满了");
}
//加入元素,计数器累加,通知另外一个线程
list.add(object);
System.out.println("新加入的元素:"+object);
count.incrementAndGet();
lock.notify();
}
}
//7.take一个对象
public Object take(){
Object ret =null;
synchronized (lock){
while(count.get()==this.minSize){
try {
lock.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
//移除元素,计数器减去一个,唤醒另一个线程
ret=list.removeFirst();
count.decrementAndGet();
lock.notify();
}
return ret;
}
public Integer getSize(){
return this.count.get();
}
public static void main(String[] args) {
Myqueue myqueue= new Myqueue(5);
myqueue.put("a");
myqueue.put("b");
myqueue.put("c");
myqueue.put("d");
myqueue.put("e");
System.out.println("当前容器的长度"+myqueue.getSize());
Thread t1= new Thread(new Runnable() {
@Override
public void run() {
myqueue.put("f");
myqueue.put("g");
}
},"t1");
t1.start();
Thread t2= new Thread(new Runnable() {
@Override
public void run() {
Object obj = myqueue.take();
System.out.println("移除的元素"+obj);
Object obj2 = myqueue.take();
System.out.println("移除的元素"+obj2);
Object obj3 = myqueue.take();
System.out.println("移除的元素"+obj3);
}
},"t2");
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
t2.start();
}
}
执行结果如下:
新加入的元素:a
新加入的元素:b
新加入的元素:c
新加入的元素:d
新加入的元素:e
当前容器的长度5
队列已经满了
移除的元素a
新加入的元素:f
移除的元素b
队列已经满了
新加入的元素:g
移除的元素c
上述就是两个线程之间通信的简单小demo,上手之后,线程的一些操作就没有那么的模糊了。