Synchronized版
public class A{
public static void main(String[] args){
Data data = new Data();
new Tread(() -> {
for(int i = 0; i < 10; i++){
try{
data.increment();
}catch(InterruptedException e){
e.printStackTrace();
}
}
}, "A").start();
new Thread(() -> {
for(int i = 0; i < 10; i++){
try{
data.decrement();
}catch(InterruptedException e){
e.printStackTrace();
}
}
}, "B").start();
}
}
class Data{
private int number = 0;
public synchronized void increment() throws InterruptedException{
if(number != 0){
this.wait();
}
number++;
this.notifyAll();
}
public synchronized void decrement() throws InterruptedException{
if(number == 0){
this.wait();
}
number--;
this.notifyAll();
}
}
当存在多个线程时,使用if判断会造成线程虚假唤醒问题,应该使用while来判断
public class A{
public static void main(String[] args){
Data data = new Data();
new Tread(() -> {
for(int i = 0; i < 10; i++){
try{
data.increment();
}catch(InterruptedException e){
e.printStackTrace();
}
}
}, "A").start();
new Thread(() -> {
for(int i = 0; i < 10; i++){
try{
data.decrement();
}catch(InterruptedException e){
e.printStackTrace();
}
}
}, "B").start();
new Thread(() -> {
for(int i = 0; i < 10; i++){
try{
data.decrement();
}catch(InterruptedException e){
e.printStackTrace();
}
}
}, "C").start();
new Thread(() -> {
for(int i = 0; i < 10; i++){
try{
data.decrement();
}catch(InterruptedException e){
e.printStackTrace();
}
}
}, "D").start();
}
}
class Data{
private int number = 0;
public synchronized void increment() throws InterruptedException{
while(number != 0){
this.wait();
}
number++;
this.notifyAll();
}
public synchronized void decrement() throws InterruptedException{
while(number == 0){
this.wait();
}
number--;
this.notifyAll();
}
}
Lock版
public class A{
public static void main(String[] args){
Data data = new Data();
new Tread(() -> {
for(int i = 0; i < 10; i++){
try{
data.increment();
}catch(InterruptedException e){
e.printStackTrace();
}
}
}, "A").start();
new Thread(() -> {
for(int i = 0; i < 10; i++){
try{
data.decrement();
}catch(InterruptedException e){
e.printStackTrace();
}
}
}, "B").start();
new Thread(() -> {
for(int i = 0; i < 10; i++){
try{
data.decrement();
}catch(InterruptedException e){
e.printStackTrace();
}
}
}, "C").start();
new Thread(() -> {
for(int i = 0; i < 10; i++){
try{
data.decrement();
}catch(InterruptedException e){
e.printStackTrace();
}
}
}, "D").start();
}
}
class Data{
private int number = 0;
Lock lock = new RentrantLock();
Condition condition = lock.newCondition();
public void increment() throws InterruptedException{
lock.lock();
try{
while(number != 0){
condition.await();
}
number++;
condition.signalAll();
}catch(){
e.printStackTrace();
}finally{
lock.unlock();
}
}
public void decrement() throws InterruptedException{
lock.lock();
try{
while(number == 0){
condition.await();
}
number--;
condition.signalAll();
}catch(){
e.printStackTrace();
}finally{
lock.unlock();
}
}