面试常见的笔试题:单例模式,八大排序算法,生产者和消费者,死锁
生产者和消费者问题Synchronized版
package com.liao.lesson1;
public class Test02 {
public static void main(String[] args) {
A a = new A();
new Thread(()->{
for (int i = 0; i < 10; i++) {
try {
a.increment();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
},"A").start();
new Thread(()->{
for (int i = 0; i < 10; i++) {
try {
a.increment();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
},"B").start();
}
}
class A{
private int number;
public synchronized void increment() throws InterruptedException {
if (number!=0){
this.wait();
}
number++;
notifyAll();
System.out.println(Thread.currentThread().getName()+"--->"+number);
}
public synchronized void decrement() throws InterruptedException {
if (number==0){
this.wait();
}
number--;
notifyAll();
System.out.println(Thread.currentThread().getName()+"--->"+number);
}
}
问题存在:这是两个线程的时候,那有4个线程的时候会出现什么问题?
这个时候通过代码我们发现线程。出错了,线程不安全了,不再只有0,1,两种结果,会出现3,或4。
使用if一次性判断会出现虚假唤醒问题,解决办法就是将if判断改为while判断
package com.liao.lesson1;
public class Test03 {
public static void main(String[] args) {
com.liao.lesson1.A a = new com.liao.lesson1.A();
new Thread(()->{
for (int i = 0; i < 10; i++) {
try {
a.increment();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
},"A").start();
new Thread(()->{
for (int i = 0; i < 10; i++) {
try {
a.increment();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
},"B").start();
new Thread(()->{
for (int i = 0; i < 10; i++) {
try {
a.decrement();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
},"C").start();
new Thread(()->{
for (int i = 0; i < 10; i++) {
try {
a.decrement();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
},"D").start();
}
}
class B{
private int number;
public synchronized void increment() throws InterruptedException {
while (number!=0){
this.wait();
}
number++;
notifyAll();
System.out.println(Thread.currentThread().getName()+"--->"+number);
}
public synchronized void decrement() throws InterruptedException {
while (number==0){
this.wait();
}
number--;
notifyAll();
System.out.println(Thread.currentThread().getName()+"--->"+number);
}
}
while判断的话,就是防止两个线程同时进入,其中一个等待