涉及到线程间的通信问题,在程序层面来说可以通过线程的等待和唤醒来实现线程之间的通知。
先创建奇偶线程类
public class OddEvenThread implements Runnable {
private volatile int i = 0;
private Object lock = new Object();
@Override
public void run() {
for(;;) {
synchronized (lock) {
if (i > 100) {
break;
}
if ((i % 2) == 0) {
System.out.println("even: " + i++);
} else {
System.out.println("odd: " + i++);
}
try {
// 唤醒所有锁住这个对象的线程 让出锁
lock.notifyAll();
// 后续再锁住自己这个线程
lock.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}
调用的代码很简单
OddEvenThread oddEvenThread = new OddEvenThread();
new Thread(oddEvenThread).start();
new Thread(oddEvenThread).start();
打印完数字后,让出锁,是其他线程可以运行,最后锁住自己的线程,等待唤醒
后续想想,还有其他的方式,可以尝试使用concurrent包里面的lock来枷锁,同理也是可以完成这个功能的
只需要略微修改一下lock的方式
public class OddEvenThread implements Runnable {
private volatile int i = 0;
private Lock lock = new ReentrantLock();
private Condition condition = lock.newCondition();
@Override
public void run() {
for(;;) {
try {
lock.lock();
if (i > 100) {
break;
}
if ((i % 2) == 0) {
System.out.println("even: " + i++);
} else {
System.out.println("odd: " + i++);
}
try {
condition.signalAll();
condition.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
} finally {
lock.unlock();
}
}
}
}
上面两种实现方式都是比较常见的线程等待,也可以利用阻塞队列来实现线程间的通信,采用的是及时同步队列SynnhronousQueue
private SynchronousQueue<Integer> oddSynchronousQueue = new SynchronousQueue();
private SynchronousQueue<Integer> evenSynchronousQueue = new SynchronousQueue();
public class OddThread implements Runnable {
@Override
public void run() {
for(;;) {
try {
int i = oddSynchronousQueue.take();
System.out.println("odd: " + i++);
evenSynchronousQueue.put(i);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
public class EvenThread implements Runnable {
@Override
public void run() {
for(;;) {
try {
int i = evenSynchronousQueue.take();
System.out.println("even: " + i++);
oddSynchronousQueue.put(i);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
public void init() throws InterruptedException {
OddThread oddThread = new OddThread();
EvenThread evenThread = new EvenThread();
new Thread(oddThread).start();
new Thread(evenThread).start();
oddSynchronousQueue.put(1);
}
其中一个线程获取到值后,会给另外的线程通信,同时阻塞自己所在的线程。
这样就可以做到交替传输数据,免去了唤醒线程这种耗时操作。