常见的一道面试题,认真想一想,自己写出来还是对wait()和notify()的理解有好处的,但是还是推荐使用reentrantlock去实现,更灵活吧。
package com.ilovewl.interview.concurrent;
/**
* 主要就是两个线程占用同一把锁,一个标志位保存当前应该输出偶数还是奇数
* @author liuchangrong
*/
public class PrintNumber {
private static final int MAX_NUMBER = 10;
public static void main(String[] args) {
Counter lock = new Counter();
new Thread(new A(lock)).start();
new Thread(new B(lock)).start();
}
//输出偶数
static class A implements Runnable {
int init = 0;
boolean flag = true;
private Counter lock;
public A(Counter lock) {
this.lock = lock;
}
@Override
public void run() {
while (init <= MAX_NUMBER) {
synchronized (lock) {
if(!lock.odd) {
try {
lock.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println(init);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
init = init + 2;
//通知另外一个进程
lock.notifyAll();
//改变下一个状态
lock.odd = !lock.odd;
}
}
}
}
//输出奇数
static class B implements Runnable {
int init = 1;
private Counter lock;
public B(Counter lock) {
this.lock = lock;
}
@Override
public void run() {
while (init <= MAX_NUMBER ) {
synchronized (lock) {
if(lock.odd) {
try {
lock.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println(init);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
init = init + 2;
lock.notifyAll();
lock.odd = !lock.odd;
}
}
}
}
static class Counter{
//初始值为true,表示输出偶数,奇数的线程就等待
//如果为false,表示输出奇数,偶数的线程就等待
public boolean odd = true;
}
}
使用ReentrantLock实现:
package com.ilovewl.interview.concurrent;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock;
/**
* 使用ReentrantLock打印奇数和偶数
* @author liuchangrong
*/
public class PrintNumber2 {
private static final int MAX_NUMBER = 10;
static Counter lock = new Counter();
static Condition a = lock.newCondition();
static Condition b = lock.newCondition();
public static void main(String[] args) {
new Thread(new A(lock)).start();
new Thread(new B(lock)).start();
}
//输出偶数
static class A implements Runnable {
int init = 0;
private Counter lock;
public A(Counter lock) {
this.lock = lock;
}
@Override
public void run() {
while (init <= MAX_NUMBER) {
lock.lock();
try {
if (!lock.odd) {
try {
a.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println(init);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
init = init + 2;
b.signal();
lock.odd = !lock.odd;
} finally {
lock.unlock();
}
}
}
}
//输出奇数
static class B implements Runnable {
int init = 1;
private Counter lock;
public B(Counter lock) {
this.lock = lock;
}
@Override
public void run() {
while (init <= MAX_NUMBER ) {
lock.lock();
try {
if (lock.odd) {
try {
b.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println(init);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
init = init + 2;
a.signal();
lock.odd = !lock.odd;
}finally {
lock.unlock();
}
}
}
}
static class Counter extends ReentrantLock {
//初始值为true,表示先输出偶数,奇数的线程就等待
public boolean odd = true;
public Counter(){
super(true);
}
}
}
如果有什么问题的话,欢迎留言讨论!