您的位置:首页 > 大数据 > 人工智能

使用Lock,wait/notify,Semaphore三种方式实现多线程通信

2013-10-08 14:56 477 查看
java的多线程通信有Lock,wait/notify,Semaphore三种方式,以一道常见面试题来简单演示这三种多线程通信方式。

两个线程循环间隔打印指定内容,一个打印从1到52的数字,一个打印从A到Z的字母,打印输出如下:

1

2

A

3

4

B

......

51

52

Z

使用Lock实现代码如下:

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

public class ThreadCommunicationTest {

private final Lock lock = new ReentrantLock();

private final Condition conditionA = lock.newCondition();
private final Condition conditionB = lock.newCondition();

private static char currentThread = 'A';

public static void main(String[] args) {

ThreadCommunicationTest test = new ThreadCommunicationTest();

ExecutorService service = Executors.newCachedThreadPool();

service.execute(test.new RunnableA());
service.execute(test.new RunnableB());

service.shutdown();

}

private class RunnableA implements Runnable {
public void run() {
for (int i = 1; i <= 52; i++) {
lock.lock();

try {
while (currentThread != 'A') {
try {
conditionA.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
}

System.out.println(i);
if (i % 2 == 0) {
currentThread = 'B';
conditionB.signal();
}
} finally {
lock.unlock();
}
}

}

}

private class RunnableB implements Runnable {
public void run() {
for (char c = 'A'; c <= 'Z'; c++) {
lock.lock();
try {
while (currentThread != 'B') {
try {
conditionB.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
}

System.out.println(c);
currentThread = 'A';
conditionA.signal();
} finally {
lock.unlock();
}
}

}

}
}

使用wait/notify实现代码如下:

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class ThreadCommunicationTest2 {

private static char currentThread = 'A';
private final Object t = new Object(); //使用一个同步对象保证两个线程之间每一时刻只有一个线程工作

public static void main(String[] args) {
ThreadCommunicationTest2 test = new ThreadCommunicationTest2();
ExecutorService service = Executors.newCachedThreadPool();

service.execute(test.new RunnableA());
service.execute(test.new RunnableB());

service.shutdown();
}

private class RunnableA implements Runnable {
public void run() {
for (int i = 1; i <= 52; i++) {
synchronized (t) {
if(currentThread != 'A'){
try {
t.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println(i);
if (i % 2 == 0) {
currentThread = 'B';
t.notifyAll();
}
}
}
}
}

private class RunnableB implements Runnable {
public void run() {
for (char c = 'A'; c <= 'Z'; c++) {
synchronized (t) {
if(currentThread != 'B'){
try {
t.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println(c);
currentThread = 'A';
t.notifyAll();
}
}
}
}

}

使用Semaphore信号量的代码如下:

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Semaphore;

public class ThreadCommunicationTest3 {

private final Semaphore semap = new Semaphore(1);//创建一个只有1个许可的信号量,保证两个线程间每一时刻只有一个在工作

private static char currentThread = 'A';

public static void main(String[] args) {

ThreadCommunicationTest3 test = new ThreadCommunicationTest3();

ExecutorService service = Executors.newCachedThreadPool();

service.execute(test.new RunnableA());
service.execute(test.new RunnableB());

service.shutdown();

}

private class RunnableA implements Runnable {
public void run() {
for (int i = 1; i <= 52; i++) {
try {
semap.acquire();
while (currentThread != 'A') {
semap.release();
}
System.out.println(i);
if (i % 2 == 0) {
currentThread = 'B';
}
} catch (Exception e) {
e.printStackTrace();
} finally {
semap.release();
}
}
}
}

private class RunnableB implements Runnable {
public void run() {
for (char c = 'A'; c <= 'Z'; c++) {
try {
semap.acquire();
while (currentThread != 'B') {
semap.release();
}
System.out.println(c);
currentThread = 'A';
} catch (Exception e) {
e.printStackTrace();
} finally {
semap.release();
}
}
}

}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐