阻塞和非阻塞:指的是客户端等待消息处理时本身的状态,是挂起还是继续干别的。
同步和异步:指的是对于消息结果的获取方式,是客户端主动获取,还是由服务端进行通知或回调。
同步阻塞:客户端主动获取结果,并在结果返回前挂起
同步非阻塞:客户端主动获取结果,在结果返回前可以干别的事,然后通过定时轮询的方式去获取结果
异步阻塞:客户端不主动获取结果,服务端主动通知或者回调前,客户端挂起等待结果(对结果强依赖)
异步非阻塞:客户端不主动获取结果,在服务端通知或者回调前,客户端可以去干其他事(对结果不是强依赖)
同步阻塞示例:
/**
* 同步 阻塞
*/
private static void synchronizedBlocking() {
long start = System.currentTimeMillis();
List<String> result = new ArrayList<>();
for (int i = 0; i < 10; i++) {
MyThread thread = new MyThread(i);
thread.start();
// 客户端主动获取结果,并在结果返回前挂起
result.add(thread.getString());
}
System.out.println("同步阻塞执行时间:" + (System.currentTimeMillis() - start));
}
同步非阻塞示例:
/**
* 同步 非阻塞
*/
private static void synchronizedUnBlocking() {
long start = System.currentTimeMillis();
List<String> result = new ArrayList<>();
List<MyThread> threads = new ArrayList<>();
for (int i = 0; i < 10; i++) {
MyThread thread = new MyThread(i);
thread.start();
// 在结果返回前可以干别的事,即继续执行循环
threads.add(thread);
}
for (int i = 0; i < 10; i++) {
MyThread thread = threads.get(i);
// 客户端主动获取结果
result.add(thread.getString());
}
System.out.println("同步非阻塞执行时间:" + (System.currentTimeMillis() - start));
}
同步示例的其他代码:
private static class MyThread extends Thread {
private int index;
private String result;
public MyThread(int index) {
this.index = index;
}
@Override
public void run() {
try {
sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
result = index + "";
}
public String getString() {
while (result == null) {
try {
sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
return result;
}
}
异步阻塞示例:
/**
* 异步 阻塞
*/
private static void unSynchronizedBlocking() {
long start = System.currentTimeMillis();
List<String> result = new Vector<>();
for (int i = 0; i < 10; i++) {
MyThread1 thread = new MyThread1(i, result);
thread.start();
// 客户端不主动获取结果(这里是监控某个状态),服务端主动通知或者回调前,客户端挂起等待结果
while (result.size() != (i + 1)) {
try {
Thread.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
System.out.println("异步阻塞执行时间:" + (System.currentTimeMillis() - start));
}
异步非阻塞示例:
/**
* 异步 非阻塞
*/
private static void unSynchronizedUnBlocking() {
long start = System.currentTimeMillis();
List<String> result = new Vector<>();
for (int i = 0; i < 10; i++) {
MyThread1 thread = new MyThread1(i, result);
// 客户端不主动获取结果,在服务端通知或者回调前,客户端可以去干其他事
thread.start();
}
// 客户端不主动获取结果(这里是监控某个状态),在服务端通知或者回调前,客户端可以去干其他事(对结果不是强依赖)
while (result.size() != 10) {
try {
Thread.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println("异步非阻塞执行时间:" + (System.currentTimeMillis() - start));
}
异步方式的其他代码:
private static class MyThread1 extends Thread {
private int index;
private List<String> list;
public MyThread1(int index, List<String> list) {
this.index = index;
this.list = list;
}
@Override
public void run() {
try {
sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
list.add(index + "");
}
}
上述几种方式的执行结果为:
同步阻塞执行时间:10021
同步非阻塞执行时间:1005
异步阻塞执行时间:10016
异步非阻塞执行时间:1002
每次结果都不一样,总体说来,阻塞方式性能比非阻塞方式低(这个很明显),同步方式性能比异步方式低(但这个不明显)