Created
July 20, 2019 05:45
-
-
Save alonWang/d7529b37cd52058e3cbb6117538610aa to your computer and use it in GitHub Desktop.
Java Thread Spurious WakeUp Demo
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* @description: 参考了 https://www.jianshu.com/p/da312eee4ac4 | |
* @author: alonwang | |
* @create: 2019-07-19 15:54 | |
**/ | |
public class SpuriousWakeUp { | |
private final Object lock = new Object(); | |
private int product = 0; | |
//如果没有产品,在lock对象上等待唤醒,如果有产品,消费. | |
private Runnable consumer = () -> { | |
System.out.println(Thread.currentThread().getName() + " prepare consume"); | |
synchronized (lock) { | |
if (product <= 0) {//替换为while解决线程虚假唤醒问题 | |
try { | |
System.out.println(Thread.currentThread().getName() + " wait"); | |
lock.wait(); | |
} catch (InterruptedException e) { | |
e.printStackTrace(); | |
} | |
System.out.println(Thread.currentThread().getName() + " wakeup"); | |
} | |
product--; | |
System.out.println(Thread.currentThread().getName() + " consumed product:" + product); | |
if (product < 0) { | |
System.err.println(Thread.currentThread().getName() + " spurious lock happend, product: " + product); | |
} | |
} | |
}; | |
//生产一个产品然后唤醒一个在lock对象上等待的consumer | |
private Runnable producer = () -> { | |
System.out.println(Thread.currentThread().getName() + " prepare produce"); | |
synchronized (lock) { | |
product += 1; | |
System.out.println(Thread.currentThread().getName() + "produced product: " + product); | |
lock.notify(); | |
} | |
}; | |
public void producerAndConsumer() { | |
// 启动2个consumer,1个producer | |
Thread c1 = new Thread(consumer); | |
Thread c2 = new Thread(consumer); | |
Thread p = new Thread(producer); | |
c1.start(); | |
c2.start(); | |
p.start(); | |
} | |
public static void main(String[] args) { | |
//运行100次,以便触发异常现象 | |
for (int i = 0; i < 100; i++) { | |
new SpuriousWakeUp().producerAndConsumer(); | |
} | |
try { | |
Thread.sleep(5000); | |
} catch (InterruptedException e) { | |
e.printStackTrace(); | |
} | |
System.exit(0); | |
} | |
} | |
作者:alonwang | |
链接:https://juejin.im/post/5d32a6545188257f3850d514 | |
来源:掘金 | |
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment