- 线程进入临界区后,如果发现只有满足了某个条件后才能继续向下执行,则此时可以使用一个条件对象管理这个线程。
- 条件对象负责将不满足条件的线程添加到等待集中,使得该线程进入阻塞状态,直到其他线程利用该条件对象解锁该线程的阻塞状态。
- Java中的每个对象都有一个内部对象锁,内部对象锁只有一个关联条件。
- 线程间通信的方法:
- wait() / await():添加线程到等待集中。
- notifyAll() / signalAll():解锁等待集中所有等待线程的阻塞状态。
- notify() / signal():解锁等待集中随机一个等待线程的阻塞状态。
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
public class ThreadCommunication {
public static void main(String[] args) {
System.out.println("---非静态synchronized代码块---");
Test1 test1 = new Test1();
Thread thread11 = new Thread(test1);
Thread thread12 = new Thread(test1);
thread11.start();
thread12.start();
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("---静态synchronized代码块---");
Thread thread21 = new Thread(new Test2());
Thread thread22 = new Thread(new Test2());
thread21.start();
thread22.start();
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("---非静态synchronized方法---");
Test3 test3 = new Test3();
Thread thread31 = new Thread(test3);
Thread thread32 = new Thread(test3);
thread31.start();
thread32.start();
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("---静态synchronized方法---");
Thread thread41 = new Thread(new Test4());
Thread thread42 = new Thread(new Test4());
thread41.start();
thread42.start();
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("---非静态ReentrantLock类---");
Test5 test5 = new Test5();
Thread thread51 = new Thread(test5);
Thread thread52 = new Thread(test5);
thread51.start();
thread52.start();
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("---静态ReentrantLock类---");
Thread thread61 = new Thread(new Test6());
Thread thread62 = new Thread(new Test6());
thread61.start();
thread62.start();
}
}
class Test1 implements Runnable {
private int number = 3;
@Override
public void run() {
while (number >= 0) {
synchronized (this) {
if (number >= 0) {
while (Thread.currentThread().getId() % 2 != number % 2) {
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println("Thread-" + Thread.currentThread().getId() + ":" + number);
number--;
notifyAll();
}
}
}
}
}
class Test2 implements Runnable {
private static int number = 3;
@Override
public void run() {
while (number >= 0) {
synchronized (Test2.class) {
if (number >= 0) {
while (Thread.currentThread().getId() % 2 != number % 2) {
try {
Test2.class.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println("Thread-" + Thread.currentThread().getId() + ":" + number);
number--;
Test2.class.notifyAll();
}
}
}
}
}
class Test3 implements Runnable {
private int number = 3;
@Override
public void run() {
while (number >= 0) {
print();
}
}
private synchronized void print() {
if (number >= 0) {
while (Thread.currentThread().getId() % 2 != number % 2) {
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println("Thread-" + Thread.currentThread().getId() + ":" + number);
number--;
notifyAll();
}
}
}
class Test4 implements Runnable {
private static int number = 3;
@Override
public void run() {
while (number >= 0) {
print();
}
}
private static synchronized void print() {
if (number >= 0) {
while (Thread.currentThread().getId() % 2 != number % 2) {
try {
Test4.class.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println("Thread-" + Thread.currentThread().getId() + ":" + number);
number--;
Test4.class.notifyAll();
}
}
}
class Test5 implements Runnable {
private int number = 3;
private Lock lock = new ReentrantLock();
private Condition condition = lock.newCondition();
@Override
public void run() {
while (number >= 0) {
lock.lock();
try {
if (number >= 0) {
while (Thread.currentThread().getId() % 2 != number % 2) {
try {
condition.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println("Thread-" + Thread.currentThread().getId() + ":" + number);
number--;
condition.signalAll();
}
} finally {
lock.unlock();
}
}
}
}
class Test6 implements Runnable {
private static int number = 3;
private static Lock lock = new ReentrantLock();
private static Condition condition = lock.newCondition();
@Override
public void run() {
while (number >= 0) {
lock.lock();
try {
if (number >= 0) {
while (Thread.currentThread().getId() % 2 != number % 2) {
try {
condition.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println("Thread-" + Thread.currentThread().getId() + ":" + number);
number--;
condition.signalAll();
}
} finally {
lock.unlock();
}
}
}
}
![在这里插入图片描述](https://i-blog.csdnimg.cn/blog_migrate/6020ea04ac9fd9ca07e7003b907b3611.png#pic_center)