两个线程交替打印
交替打印一
主要是wait 和notify的应用,可以参见 http://my.oschina.net/xinxingegeya/blog/345816
利用wait 和notify实现两个线程交替打印0-100,代码如下,
/**
* 两个线程交替打印数字
* <p/>
* 核心思想就是如何控制wait和notify
*/
public class Main {
static final Object lock = new Object();
static int num1 = 0;
static int num2 = 1;
static int end = 100;
/**
* volatile
* 保证两个线程之间的内存可见性
* <p/>
* 0 for thread a to print
* 1 for thread b to print
*/
volatile static int state = 0;
public static void main(String args[]) {
// 两个线程 交替打印字符串
Thread a = new Thread() {
public void run() {
/**
* 从语法角度来说就是Obj.wait(),Obj.notify必须在synchronized(Obj){...}语句块内
*/
while (true) {
synchronized (lock) {
if (state == 1) {
try {
/**
* 当state=1时,需要释放对象锁,同时本线程休眠,
* 直到有其它线程调用对象的notify()唤醒该线程,才能继续获取对象锁,并继续执行
*/
lock.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
state = 1;
if (num1 >= end) {
break;
}
System.out.println(num1);
num1 += 2;
/**
* notify()唤醒等待该对象锁的线程,但有一点需要注意的是notify()调用后,
* 并不是马上就释放对象锁的,而是在相应的synchronized(){}语句块执行结束,
* 自动释放锁后,JVM会在wait()对象锁的线程中随机选取一线程,赋予其对象锁,唤醒线程,继续执行.
* 这样就提供了在线程间同步、唤醒的操作.
*/
lock.notify();
}
}
}
};
Thread b = new Thread() {
public void run() {
while (true) {
synchronized (lock) {
if (state == 0) {
try {
lock.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
state = 0;
if (num2 >= end) {
break;
}
System.out.println(num2);
num2 += 2;
lock.notify();
}
}
}
};
b.start();
a.start();
}
}
交替打印二
使用显示锁和条件对列实现线程的交替打印,
关于条件对列,http://my.oschina.net/xinxingegeya/blog/309323
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
/**
* 使用条件队列实现线程的交替打印
*/
public class PrintMain {
static final Lock lock = new ReentrantLock();
static final Condition threadAPrint = lock.newCondition();
static final Condition threadBPrint = lock.newCondition();
static int num1 = 0;
static int num2 = 1;
static int end = 100;
volatile static int state = 0;
public static void main(String args[]) {
final Thread threadA = new Thread(new Runnable() {
@Override
public void run() {
while (true) {
/**
* 获取锁,获取锁不成功时,当前线程休眠,直到获取锁,继续执行
*/
lock.lock();
try {
if (state == 1) {
try {
/**
* Causes the current thread to wait until it is signalled or
* {Thread#interrupt interrupted}.
*
* The lock associated with this {Condition} is atomically
* released and the current thread becomes disabled for thread scheduling
* purposes and lies dormant until <em>one</em> of four things happens...
*/
threadAPrint.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
state = 1;
if (num1 >= end) {
break;
}
System.out.println(num1);
num1 += 2;
/**
* Wakes up one waiting thread.
*/
threadBPrint.signal();
} finally {
lock.unlock();
}
}
}
});
Thread threadB = new Thread(new Runnable() {
@Override
public void run() {
while (true) {
lock.lock();
try {
if (state == 0) {
try {
threadBPrint.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
state = 0;
if (num2 >= end) {
break;
}
System.out.println(num2);
num2 += 2;
threadAPrint.signal();
} finally {
lock.unlock();
}
}
}
});
threadA.start();
threadB.start();
}
}
======END======