题目:
两个线程,可以操作初始值为0的变量。实现一个线程对该变量加1,一个线程对该变量减一实现交替,来10轮,变量初始值为0
class AirConditioner{
private int number=0;
synchronized public void increase() throws InterruptedException {
if(number != 0){
this.wait();
}
number++;
System.out.println(Thread.currentThread().getName() +"\t"+ number);
this.notifyAll();
}
synchronized public void decrease() throws InterruptedException {
if(number == 0){
this.wait();
}
number--;
System.out.println(Thread.currentThread().getName() +"\t"+ number);
this.notifyAll();
}
}
public class ThreadWaitNotifyDemo {
public static void main(String[] args) {
AirConditioner airConditioner = new AirConditioner();
new Thread(()->{
for (int i = 0; i <10 ; i++) {
try {
airConditioner.increase();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
},"A").start();
new Thread(() -> {
for (int i = 0; i <10 ; i++) {
try {
airConditioner.decrease();
}catch (InterruptedException e ){
e.printStackTrace();
}
}
},"B").start();
}
}
此时运行结果正确。
当线程的数量增加为4个时,两个实现加一,两个实现减一。
public class ThreadWaitNotifyDemo {
public static void main(String[] args) {
AirConditioner airConditioner = new AirConditioner();
new Thread(()->{
for (int i = 0; i <10 ; i++) {
try {
airConditioner.increase();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
},"A").start();
new Thread(() -> {
for (int i = 0; i <10 ; i++) {
try {
airConditioner.decrease();
}catch (InterruptedException e ){
e.printStackTrace();
}
}
},"B").start();
new Thread(() -> {
for (int i = 0; i <10 ; i++) {
try {
airConditioner.increase();
}catch (InterruptedException e ){
e.printStackTrace();
}
}
},"C").start();
new Thread(() -> {
for (int i = 0; i <10 ; i++) {
try {
airConditioner.decrease();
}catch (InterruptedException e ){
e.printStackTrace();
}
}
},"D").start();
}
}
此时结果就不正确了。
这是因为不能使用if
要是用where
。
更改以后的代码
synchronized public void decrease() throws InterruptedException {
while( number != 0){
this.wait();
}
number++;
System.out.println(Thread.currentThread().getName() +"\t"+ number);
this.notifyAll();
}
synchronized public void increase() throws InterruptedException {
while(number == 0){
this.wait();
}
number--;
System.out.println(Thread.currentThread().getName() +"\t"+ number);
this.notifyAll();
}
这样就不会出现上面的问题了。
第二种方法:采用JUC的方法。java.util.concurrent.locks
。
Lock是一个接口。
Interface Lock
有以下实现类: ReentrantLock, ReentrantReadWriteLock.ReadLock, ReentrantReadWriteLock.WriteLock。其中我们需要用到ReentrantLock
。
class AirConditioner03 {
private int number = 0;
Lock lock = new ReentrantLock();
Condition condition =lock.newCondition();
public void decrease() {
try {
lock.lock();
while (number != 0){
condition.await();
}
number++;
System.out.println(Thread.currentThread().getName()+"\t"+ number);
condition.signalAll();
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
lock.unlock();
}
}
public void increase() {
try{
lock.lock();
while (number == 0){
condition.await();
}
number--;
System.out.println(Thread.currentThread().getName()+"\t"+ number);
condition.signalAll();
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
lock.unlock();
}
}
}
public class Version3 {
public static void main(String[] args) {
AirConditioner03 airConditioner03 = new AirConditioner03();
new Thread(()->{
for (int i = 0; i <10 ; i++) {
airConditioner03.decrease();
}
},"A").start();
new Thread(()->{
for (int i = 0; i <10 ; i++) {
airConditioner03.increase();
}
},"B").start();
new Thread(()->{
for (int i = 0; i <10 ; i++) {
airConditioner03.decrease();
}
},"C").start();
new Thread(()->{
for (int i = 0; i <10 ; i++) {
airConditioner03.increase();
}
},"D").start();
}
}
JAVA8 api对此的解释