共享内存
例如我们之前利用volatile变量来停止线程就是一种共享内存的方式
public class RunTaskCase3 {
private volatile boolean stopFlag;
private Thread taskThread;
public void start() {
taskThread = new Thread(() -> {
while (stopFlag) {
try {
System.out.println("doSomething");
TimeUnit.MICROSECONDS.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
taskThread.start();
}
public void stop() {
stopFlag = true;
taskThread.interrupt();
}
}
等待通知
public class WaitNotify {
private static Object lock = new Object();
public static void main(String[] args) throws InterruptedException {
Thread waitThread = new Thread(new Wait());
waitThread.start();
TimeUnit.SECONDS.sleep(1);
Thread notifyThread = new Thread(new Notify());
notifyThread.start();
}
private static class Wait implements Runnable {
@Override
public void run() {
synchronized (lock) {
try {
System.out.println("lock wait start");
lock.wait();
System.out.println("lock wait end");
} catch (InterruptedException e) {
e.printStackTrace();
}
// 条件满足,完成工作
System.out.println("run finish");
}
}
}
private static class Notify implements Runnable {
@Override
public void run() {
synchronized (lock) {
System.out.println("lock notify start");
lock.notify();
System.out.println("lock notify end");
}
}
}
}
Wait线程不满足条件,调用wait方法等待,Notify线程调用notify方法通知Wait线程现在满足条件了,可以继续运行了。
lock wait start
lock notify start
lock notify end
lock wait end
run finish
wait,notify 为什么要和synchronized一起使用?
当多个线程调用同一个对象的wait和notify方法时,需要保证线程安全,因此需要加锁
sleep和wait有哪些区别?
虽然sleep和wait的表现行为都是等待,但是完全是2个不相关的方法。
- sleep是单纯的等待方法,和wait是用来进行线程通信的方法,当资源得不到满足时不得不等待。因此这2个方法被放在不同的类中,sleep是Thread类的方法,wait是Object类的方法。
- sleep方法可以在任何地方使用,wait只能在synchronized方法或synchronized块中使用
- Thread.sleep只会让出CPU,不会释放对象锁
- Object.wait不仅让出CPU,还会释放对象锁。只有针对此对象调用notify()方法或者时间到了,才能再次执行
wait的时候为什么要释放锁
当线程a进入synchronized(obj)块中,就是对obj上了锁,此时调用wait将进入阻塞状态,如果此时不释放锁,那么其他线程就不会进入synchronized块中,自然就无法调用notify方法,此时就会造成死锁