一、java.util.concurrent包与Acitve Object模式
将使用java.util.concurrent包来编写一个与示例程序(Active Object模式)几乎具有相同功能的示例程序。
二、示例程序
1.示例程序类和接口一览表
类和接口名 | 内容说明 |
---|---|
Main.java | 测试示例程序行为的类 |
MakerClientThread.java | 委托ActiveObject来生成字符串的线程 |
DisplayClientThread.java | 委托AcitveObject来显示字符串的线程 |
ActiveObject.java | 定义主动对象的接口 |
ActiveObjectFactory.java | 创建主动对象的类 |
AcitveObjectImpl.java | 实现了ActiveObject接口的类(替代了示例程序1的Proxy、Servant) |
MakeStringRequest.java | 对应makeString方法(生成字符串)的类 |
DisplayStringRequest.java | 对应displayString方法(显示字符串)的类 |
2.示例程序中的类
3.Main类
public class Main {
/**
* 使用ActiveObjectFactory类的createActiveObject方法创建ActiveObject对象,并启动MakerClientThread和DisplayClientThread的线程
* 在启动线程大约5s后,ActiveObject的shutdown方法会被调用。
*
* @param args
*/
public static void main(String[] args) {
ActiveObject activeObject = ActiveObjectFactory.createActiveObject();
try {
new MakerClientThread("Alice", activeObject).start();
new MakerClientThread("Bobby", activeObject).start();
new DisplayClientThread("Chris", activeObject).start();
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
System.out.println("***** shutdown *****");
activeObject.shutdown();
}
}
}
4.MakerClientThread类
public class MakerClientThread extends Thread {
/**
* 是调用ActiveObject对象的makeString方法的线程
*/
private final ActiveObject activeObject;
private final char fillchar;
public MakerClientThread(String name, ActiveObject activeObject) {
super(name);
this.activeObject = activeObject;
this.fillchar = name.charAt(0);
}
public void run() {
try {
for (int i = 0; true; i++) {
//有返回值的调用
Future<String> future = activeObject.makeString(i, fillchar);
Thread.sleep(10);
String value = future.get();
System.out.println(Thread.currentThread().getName() + ": value = " + value);
}
} catch (InterruptedException e) {
System.out.println(Thread.currentThread().getName() + ":" + e);
} catch (Exception e) {
System.out.println(Thread.currentThread().getName() + ":" + e);
}
}
}
5.DisplayClientThread类
public class DisplayClientThread extends Thread {
/**
* 与MakerClientThread类一样,也是表示调用ActiveObject对象的线程的类。
*/
private final ActiveObject activeObject;
public DisplayClientThread(String name, ActiveObject activeObject) {
super(name);
this.activeObject = activeObject;
}
public void run() {
try {
for (int i = 0; true; i++) {
//没有返回值的调用
String string = Thread.currentThread().getName() + " " + i;
activeObject.displayString(string);
Thread.sleep(200);
}
} catch (InterruptedException e) {
System.out.println(Thread.currentThread().getName() + ":" + e);
} catch (Exception e) {
System.out.println(Thread.currentThread().getName() + ":" + e);
}
}
}
6.ActiveObject接口
public interface ActiveObject {
public abstract Future<String> makeString(int count, char fillchar);
public abstract void displayString(String string);
public abstract void shutdown();
}
7.ActiveObjectFactory类
public class ActiveObjectFactory {
public static ActiveObject createActiveObject() {
return new AcitveObjectImpl();
}
}
8.AcitveObjectImpl类
//ActiveObject接口的实现类
public class AcitveObjectImpl implements ActiveObject {
/**
* AcitveObjectImpl类实现了ActiveObject接口的类,它可以进行很多工作
* ExecutorService对象的内部保存着一个线程安全的队列。
* shutdown方法是用户关于关闭service字段中保存的ExecutorService对象的方法,这样以来,ExecutorService对象就不会再接收新的请求了。
* makeString方法会创建MakeStringRequest类的实例,并submit给ExecutorService对象。
* displayString方法会创建DisplayStringRequest类的实例,并在ExecutorService中execute。
*/
private final ExecutorService service = Executors.newSingleThreadExecutor();
//终止服务
public void shutdown() {
service.shutdown();
}
//有返回值的调用
public Future<String> makeString(final int count, final char fillchar) {
//请求
class MakeStringRequest implements Callable<String> {
public String call() {
char[] buffer = new char[count];
for (int i = 0; i < count; i++) {
buffer[i] = fillchar;
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// e.printStackTrace();
}
}
return new String(buffer);
}
}
//发出请求
return service.submit(new MakeStringRequest());
}
//没有返回值的调用
public void displayString(final String string) {
//请求
class DisplayStringRequest implements Runnable {
public void run() {
try {
System.out.println("displayString: " + string);
Thread.sleep(10);
} catch (InterruptedException e) {
System.out.println(Thread.currentThread().getName() + ":" + e);
}
}
}
//发出请求
service.execute(new DisplayStringRequest());
}
}
9.示例程序的运行
displayString: Chris 0
Alice: value =
Bobby: value =
Alice: value = A
Bobby: value = B
displayString: Chris 1
displayString: Chris 2
displayString: Chris 3
displayString: Chris 4
displayString: Chris 5
Alice: value = AA
displayString: Chris 6
displayString: Chris 7
displayString: Chris 8
displayString: Chris 9
displayString: Chris 10
***** shutdown ***** //执行ActiveObject的shutdown
Chris:java.util.concurrent.RejectedExecutionException: Task com.yanchangxian.smart12.basetwo.AcitveObjectImpl$1DisplayStringRequest@1ddb555b rejected from java.util.concurrent.ThreadPoolExecutor@58d9d884[Shutting down, pool size = 1, active threads = 1, queued tasks = 15, completed tasks = 16] //Chris的下一个请求被拒绝
Bobby: value = BB
displayString: Chris 11
Bobby:java.util.concurrent.RejectedExecutionException: Task java.util.concurrent.FutureTask@68d018ef rejected from java.util.concurrent.ThreadPoolExecutor@58d9d884[Shutting down, pool size = 1, active threads = 1, queued tasks = 14, completed tasks = 17] //Bobby的下一个请求被拒绝
displayString: Chris 12
displayString: Chris 13
displayString: Chris 14
displayString: Chris 15
displayString: Chris 16
displayString: Chris 17
displayString: Chris 18
displayString: Chris 19
displayString: Chris 20
Alice: value = AAA
displayString: Chris 21
Alice:java.util.concurrent.RejectedExecutionException: Task java.util.concurrent.FutureTask@46295e2d rejected from java.util.concurrent.ThreadPoolExecutor@58d9d884[Shutting down, pool size = 1, active threads = 1, queued tasks = 3, completed tasks = 28] //Alice的下一个请求被拒绝
displayString: Chris 22
displayString: Chris 23
displayString: Chris 24