1、实验要求
使用四个线程AA,BB,CC,DD,AA,CC一个对象进行加1操作,BB,DD对一个对象进行减1操作。
2、实验步骤
(1)创建资源类
以number为依据做加减操作判断,分别在资源类中添加加减方法使用ReentrantLock对象进行上锁和解锁。
其中:
lock.lock(); // 代表上锁
lock.unlock(); // 代表解锁
condition.await(); // 类似于Object.wait(); 使当前线程等待,并释放锁。
condition.signalAll(); // 类似于Object.notifyAll(); // 唤醒所有等待中的锁
PS:
wait();操作必须要放在while循环中判断,如果使用if来做判断则会发生虚假唤醒状况。
//创建资源类
class Share {
// 初始值
private int number = 0;
// 可重入锁
private final Lock lock = new ReentrantLock();
private Condition condition = lock.newCondition();
// 加1
public void incr() throws InterruptedException {
// 上锁
lock.lock();
try {
// 判断
while (number != 0) { // 如果不为0就等待
condition.await();
}
number++;
System.out.println(Thread.currentThread().getName() + "::" + number);
// 通知
condition.signalAll();
} finally {
lock.unlock();
}
}
// 减1
public void decr() throws InterruptedException {
// 上锁
lock.lock();
try {
// 判断
while (number != 1) { // 如果不为1就等待
condition.await();
}
number--;
System.out.println(Thread.currentThread().getName() + "::" + number);
// 通知
condition.signalAll();
} finally {
lock.unlock();
}
}
}
(2)测试类
此处使用lambda表达式的方式创建线程并启动。
public class ThreadDemo2 {
public static void main(String[] args) {
Share share = new Share();
new Thread(()->{
for (int i = 0; i < 10; i++) {
try {
share.incr();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}, "AA").start();
new Thread(()->{
for (int i = 0; i < 10; i++) {
try {
share.decr();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}, "BB").start();
new Thread(()->{
for (int i = 0; i < 10; i++) {
try {
share.incr();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}, "CC").start();
new Thread(()->{
for (int i = 0; i < 10; i++) {
try {
share.decr();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}, "DD").start();
}
}
(3)测试
3、整体代码
package lock;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
public class ThreadDemo2 {
public static void main(String[] args) {
Share share = new Share();
new Thread(()->{
for (int i = 0; i < 10; i++) {
try {
share.incr();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}, "AA").start();
new Thread(()->{
for (int i = 0; i < 10; i++) {
try {
share.decr();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}, "BB").start();
new Thread(()->{
for (int i = 0; i < 10; i++) {
try {
share.incr();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}, "CC").start();
new Thread(()->{
for (int i = 0; i < 10; i++) {
try {
share.decr();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}, "DD").start();
}
}
//创建资源类
class Share {
// 初始值
private int number = 0;
// 可重入锁
private final Lock lock = new ReentrantLock();
private Condition condition = lock.newCondition();
// 加1
public void incr() throws InterruptedException {
// 上锁
lock.lock();
try {
// 判断
while (number != 0) { // 如果不为0就等待
condition.await();
}
number++;
System.out.println(Thread.currentThread().getName() + "::" + number);
// 通知
condition.signalAll();
} finally {
lock.unlock();
}
}
// 减1
public void decr() throws InterruptedException {
// 上锁
lock.lock();
try {
// 判断
while (number != 1) { // 如果不为1就等待
condition.await();
}
number--;
System.out.println(Thread.currentThread().getName() + "::" + number);
// 通知
condition.signalAll();
} finally {
lock.unlock();
}
}
}