在看多线程核心技术这本书的时候,里面提到了一句,notify()方法可以随机唤醒等待队列中等待统一资源的“一个一个线程”。突然很疑惑什么是统一共享资源,是不是随机。于是改动书上的代码实验一下,看一年运行结果。
原来代码如下
package 线程间通信.wait_notify_size5;
import java.util.ArrayList;
import java.util.List;
/**
* @Author:FuYouJie
* @Date Create in 2019/11/11 23:17
*/
public class MyList {
private static List list=new ArrayList();
public static void add(){
list.add("anyString");
}
public static int size(){
return list.size();
}
}
class ThreadA extends Thread{
private Object lock;
public ThreadA(Object lock){
super();
this.lock=lock;
}
public void run(){
try {
synchronized (lock){
if(MyList.size()!=5){
System.out.println("wait begin "+System.currentTimeMillis());
lock.wait();
System.out.println(Thread.currentThread().getName()+"运行了!");
System.out.println("wait end "+System.currentTimeMillis());
}
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
class ThreadB extends Thread{
private Object lock;
public ThreadB(Object lock){
this.lock=lock;
}
public void run(){
try {
synchronized (lock){
System.out.println(Thread.currentThread().getName()+"进来了!");
for(int i=0;i<10;i++){
MyList.add();
if (MyList.size()==5){
lock.notify();
System.out.println("已发出通知!");
}
System.out.println("添加了"+(i+1)+"个元素");
Thread.sleep(500);
}
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
class Run{
public static void main(String[] args) {
try {
Object lock=new Object();
ThreadA a1=new ThreadA(lock);
ThreadA a=new ThreadA(lock);
a.setName("A");
a.start();
Thread.sleep(50);
ThreadB b=new ThreadB(lock);
b.start();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
然后为了实验随机性,特意用数组生成多个A线程。
如下
class Run{
public static void main(String[] args) {
try {
Object lock=new Object();
/* ThreadA a1=new ThreadA(lock);
ThreadA a=new ThreadA(lock);
a.setName("A");
a.start();*/
ThreadA []arr=new ThreadA[10];
for(int i=0;i<10;i++){
arr[i]=new ThreadA(lock);
String name="a"+i+": ";
arr[i].setName(name);
arr[i].start();
}
//证明notify的随机性
/*Thread-10进来了!
添加了1个元素
添加了2个元素
添加了3个元素
添加了4个元素
已发出通知!
添加了5个元素
添加了6个元素
添加了7个元素
添加了8个元素
添加了9个元素
添加了10个元素
a1: 运行了!
wait end 1573487544552uj
*/
Thread.sleep(50);
ThreadB b=new ThreadB(lock);
b.start();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
多运行几次,可以看到并不总是a0线程,被notify唤醒,同时试验了notifyAll();的确是所有线程被唤醒。
相关源码在我的Gihub
https://github.com/FuYouJ/Code-of-Java-Multi-thread-Programming
喜欢点个Star 明天早课,所以这里只有代码,没有分析。