传统线程间通信
// 传统的线程通信
public class TraditionalThreadCommunication {
public static void main(String[] args) {
final Business business = new Business();
new Thread(new Runnable() {
@Override
public void run() {
for (int i = 1; i <= 50; i++) {
business.sub(i);
}
}
}).start();
// 注意:若将主线程代码放到子线程前执行,程序将死锁,
// 因主线程一直等待,而子线程又无法去执行改变变量值.
for (int i = 1; i <= 50; i++) {
business.main(i);
}
}
}
class Business {
// 让子线程先运行
private boolean bShouldSub = true;
public synchronized void sub(int i) {
System.out.println("sub()...");
while (!bShouldSub) {
try {
this.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
for (int j = 1; j <= 10; j++) {
System.out.println("sub thread sequence of " + j + ",loop of " + i);
}
bShouldSub = false;
this.notify();
}
public synchronized void main(int i) {
System.out.println("main()...");
while (bShouldSub) {
try {
this.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
for (int j = 1; j <= 100; j++) {
System.out.println("main thread sequence of " + j + ",loop of " + i);
}
bShouldSub = true;
this.notify();
}
}
基于Lock与Condition的线程通信
Condition的功能类似在传统线程中的wait()和notify()的功能,在等待Condition时,允许发生"虚假唤醒",这通常作为对基础平台语义的让步,对于大多数应用程序,这带来的影响很小,因Condition应总是在一个循环中被等等,并测试正被等待的状态声明,某个实现可以随意移除可能的虚假唤醒,但建议应用程序中虚假唤醒可能发生,因此总是在一个循环中等待.
public class ConditionCommunication {
public static void main(String[] args) {
final Business business = new Business();
new Thread(new Runnable() {
@Override
public void run() {
for (int i = 1; i <= 50; i++) {
business.sub(i);
}
}
}).start();
for (int i = 1; i <= 50; i++) {
business.main(i);
}
}
static class Business {
// 可重入锁
Lock lock = new ReentrantLock();
Condition condition = lock.newCondition();
// 让子线程先运行
private boolean bShouldSub = true;
public void sub(int i) {
lock.lock();
System.out.println("sub lock status:" + ((ReentrantLock)lock).isLocked());
try {
while (!bShouldSub) {
try {
condition.await();
} catch (Exception e) {
e.printStackTrace();
}
}
for (int j = 1; j <= 10; j++) {
System.out.println("sub thread sequence of " + j
+ ",loop of " + i);
}
bShouldSub = false;
condition.signal();
} finally {
lock.unlock();
}
}
public void main(int i) {
lock.lock();
System.out.println("main lock status:" + ((ReentrantLock)lock).isLocked());
try {
while (bShouldSub) {
try {
condition.await();
} catch (Exception e) {
e.printStackTrace();
}
}
for (int j = 1; j <= 100; j++) {
System.out.println("main thread sequence of " + j
+ ",loop of " + i);
}
bShouldSub = true;
condition.signal();
} finally {
lock.unlock();
}
}
}
}