线程间通讯
线程通讯的方式:
1.wait,notify等待通知
/**
* 等待线程(调用wait方法的线程)
*/
synchronized(共享对象){ //同步代码块,进入条件是获得锁
while(判断条件){ //进行wait线程任务的条件不满足时进入
共享对象.wait()
}
线程任务代码
}
/**
* 通知线程(调用notify方法的线程)
*/
synchronized(共享对象){ //同步代码块,进入条件是获得锁
线程任务代码
改变wait线程任务的条件
共享对象.notify()
}
具体例子
public class WaitNotify {
static boolean flag = true; //等待线程继续执行往下执行的条件
static Object lock = new Object(); //上锁的对象
public static void main(String[] args) throws InterruptedException {
Thread waitThread = new Thread(new WaitRunnable(),"waitThread"); //以WaitRunnable为任务类的线程
Thread notifyThread = new Thread(new NotifyRunnable(),"notifyThread"); //以NotifyRunnable为任务类的线程
waitThread.start(); //wait线程启动
Thread.sleep(2000); //主线程休眠2s
notifyThread.start(); //notify线程启动
}
/**
* Runnable等待实现类
* synchronized关键字:可以修饰方法或者以同步块的形式来使用
*/
static class WaitRunnable implements Runnable{
@Override
public void run() {
//对lock加锁
synchronized(lock){
//判断,若flag为true,则继续等待(wait)
while(flag){
try {
System.out.println(
Thread.currentThread().getName()+
"---flag为true,等待 @"+
new SimpleDateFormat("hh:mm:ss").format(new Date())
);
lock.wait(); //等待,并释放锁资源
} catch (InterruptedException e) {
e.printStackTrace();
}
}
//若flag为false,则进行工作
System.out.println(
Thread.currentThread().getName()+
"---flag为false,运行 @"+
new SimpleDateFormat("hh:mm:ss").format(new Date())
);
}
}
}
/**
* Runnable通知实现类
*/
static class NotifyRunnable implements Runnable{
@Override
public void run(){
//对lock加锁
synchronized(lock){
//以NotifyRunnable为任务类的线程释放lock锁,并进行通知后,以Wait为任务类的线程才可以跳出循环
System.out.println(
Thread.currentThread().getName()+
"---当前持有锁,释放 @"+
new SimpleDateFormat("hh:mm:ss").format(new Date())
);
lock.notifyAll(); //通知所有正在等待的线程从wait返回
flag = false;
try {
Thread.sleep(5000); //notifyThread线程休眠5s
} catch (InterruptedException e) {
e.printStackTrace();
}
}
//再次对lock加锁,并休眠
synchronized (lock){
System.out.println(
Thread.currentThread().getName()+
"---再次持有锁,休眠 @"+
new SimpleDateFormat("hh:mm:ss").format(new Date())
);
try {
Thread.sleep(2000); //再次让notifyThread线程休眠2s
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}
//该代码示例来自《Java并发编程的艺术》

notifyThread线程并不会在调用notyfiAll方法后就马上释放锁,而是在执行完synchronized代码块的内容后才释放锁。我们在notifyThread线程调用notyfiAll后,将该线程休眠5s。可以从打印结果发现,在notifyThread线程休眠的5s中,即使waitThread线程得到了通知,且继续运行的条件也已满足(flag为flase),但waitThread线程在这5s中依然没有得到执行。在notifyThread线程5s的休眠时间结束后,并从synchronized代码块退出,waitThread线程才继续执行。所以,等待线程在得到通知后,仍然需要等待通知线程释放锁,并且在尝试获得锁成功后才能真正从wait方法中返回,并继续执行
2.volatile共享内存,读写都会刷新线程私有内存
参考自:牛客

浙公网安备 33010602011771号