题目:两组线程循环打印一加,一减。打印10 次
思路:实现一个资源类,定义一个变量两个方法一个同步方法实现++,另一个同步方法--。
(使用synchronized关键字)
package com.thekingqj;
class Zi {
private int m = 0;
public synchronized void increment() throws InterruptedException {
while (m == 0) {
this.wait();
}
--m;
this.notifyAll();
System.out.println(Thread.currentThread().getName() + "\t" + m);
}
public synchronized void decrement() throws InterruptedException {
while (m != 0) {
this.wait();
}
++m;
this.notifyAll();
System.out.println(Thread.currentThread().getName() + "\t" + m);
}
}
/**
* 1. 高内聚低耦合前提下,线程操作资源类
* 2. 判断/干活/通知
* 3. 防止多线程通信时,虚假唤醒的BUG(要是用wait则必须用while判断)
*/
public class ThreadWaitNotify {
public static void main(String[] args) {
Zi zi = new Zi();
new Thread(() -> {
for (int i = 0; i < 10; i++) {
try {
zi.increment();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}, "A").start();
new Thread(() -> {
for (int i = 0; i < 10; i++) {
try {
zi.decrement();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}, "B").start();
new Thread(() -> {
for (int i = 0; i < 10; i++) {
try {
zi.decrement();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}, "C").start();
new Thread(() -> {
for (int i = 0; i < 10; i++) {
try {
zi.increment();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}, "D").start();
}
}
(使用Lock,unLock关键字)
package com.thekingqj;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
class Zi1 {
private int m = 0;
private Lock lock = new ReentrantLock();
final Condition condition = lock.newCondition();
public void increment() throws InterruptedException {
lock.lock();
try {
while (m == 0) {
condition.await();
}
--m;
condition.signalAll();
System.out.println(Thread.currentThread().getName() + "\t" + m);
} finally {
lock.unlock();
}
}
public void decrement() throws InterruptedException {
lock.lock();
try {
while (m != 0) {
condition.await();
}
++m;
condition.signalAll();
System.out.println(Thread.currentThread().getName() + "\t" + m);
} finally {
lock.unlock();
}
}
}
public class ThreadWaitNotify1 {
public static void main(String[] args) {
Zi1 zi = new Zi1();
new Thread(() -> {
for (int i = 0; i < 10; i++) {
try {
zi.increment();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}, "A").start();
new Thread(() -> {
for (int i = 0; i < 10; i++) {
try {
zi.decrement();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}, "B").start();
new Thread(() -> {
for (int i = 0; i < 10; i++) {
try {
zi.decrement();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}, "C").start();
new Thread(() -> {
for (int i = 0; i < 10; i++) {
try {
zi.increment();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}, "D").start();
}
}