java 线程 设计模式_Java多线程设计模式(四)

Future Pattern

在Thread-Per-Message Pattern中,我们研究过“收到每个请求建立一个线程”的做法,但这样的请求是不要求有返回值的。如果当需要返回值,但由于后台处理需要很久,返回值 不能马上获取,那么就可以使用 Future Pattern。Future Pattern同样会每个请求建立一个线程处理,同时会马上返回一个对象,但该对象并不是真正的返回值,真正的返回值可能现在还没有准备好,不过客户端可 以根据这个返回对象,在之后的时间来获取真正的返回值。

public interface Data {

public String getContent();

}

public class RealData implements Data {

private String content;

public RealData(int count, char c) {

System.out.println("making RealData(" + count + ", " + c + ") Begin.");

char[] buffer = new char[count];

for (int i = 0; i 

buffer[i] = c;

slowly();

}

this.content = String.valueOf(buffer);

System.out.println("making RealData(" + count + ", " + c + ") End.");

}

@Override

public String getContent() {

return this.content;

}

private void slowly() {

try {

Thread.sleep(100);

} catch (InterruptedException e) {

}

}

}

public class FutureData implements Data {

private RealData realData;

private boolean  ready = false;

public synchronized void setRealData(RealData realData) {

if (ready) {

return;

}

this.realData = realData;

this.ready = true;

notifyAll();

}

@Override

public synchronized String getContent() {

while (!ready) {

try {

wait();

} catch (InterruptedException e) {

}

}

return this.realData.getContent();

}

}

public class Host {

public Data handle(final int count, final char c) {

System.out.println("handle ( " + count + ", " + c + ") Begin.");

final FutureData futureData = new FutureData();

new Thread() {

@Override

public void run() {

RealData realData = new RealData(count, c);

futureData.setRealData(realData);

}

}.start();

System.out.println("handle ( " + count + ", " + c + ") End.");

return futureData;

}

}

public class Main {

public static void main(String[] args) {

System.out.println("main Begin.");

Host host = new Host();

Data data1 = host.handle(10, 'a');

Data data2 = host.handle(20, 'b');

Data data3 = host.handle(30, 'c');

System.out.println("main other job Begin.");

try {

Thread.sleep(2000);

} catch (InterruptedException e) {

}

System.out.println("main other job End.");

System.out.println("data1 = " + data1.getContent());

System.out.println("data2 = " + data2.getContent());

System.out.println("data3 = " + data3.getContent());

System.out.println("main End.");

}

}

在Worker Thread Pattern中,我们讨论过“方法调用”和“方法执行”的分离。而Future Pattern 分离了“准备返回值”和“使用返回值”。我们在Futtern Pattern中,可以看到设计模式Proxy Pattern的实现。

Two-Phase Termination Pattern

Two-Phase Termination

Pattern很简单,但该模式提供了一种结束线程的优雅方法。java.lang.Thread类有一个用来强制结束掉线程的stop()方法。但是

stop方法已经不建议使用(deprecated),原因是stop()方法会使实例丧失安全性的保障。使用stop()方法时,线程会抛出

java.lang.ThreadDeath异常而马上结束,即使该线程现在正在执行灵界区间(例如synchronized方法的中间),也会马上结

束。

public class CountupThread extends Thread {

private boolean isShutdown = false;

private int     count      = 0;

@Override

public void run() {

try {

while (isShutdown) {

doWork();

}

} catch (InterruptedException e) {

} finally {

doShutdown();

}

}

public void shutdownReqeust() {

this.isShutdown = true;

interrupt();

}

private void doShutdown() {

System.out.println("doShutdown: current count is " + this.count);

}

private void doWork() throws InterruptedException {

System.out.println("curren count is " + ++count);

Thread.sleep(500);

}

public static void main(String[] args) {

System.out.println("main Begin.");

CountupThread countupThread = new CountupThread();

countupThread.start();

try {

Thread.sleep(100000);

} catch (InterruptedException e) {

}

System.out.println("main : shutdown request.");

countupThread.shutdownReqeust();

System.out.println("main : join");

// 等待线程结束

try {

countupThread.join();

} catch (InterruptedException e) {

}

System.out.println("main End.");

}

}

Thread-Specific Storage Pattern

Thread-Specific Storage

Pattern就是“线程独有的存储库”、“针对每个线程提供的内存空间”的意义。java.lang.ThreadLocal的实例可以想象成一种集合

架构(collection)或许会比较好理解。ThreadLocal的实例只有一个,管理多个对象。

public class Log {

private static final ThreadLocal tsLogCollection = new ThreadLocal();

public static void println(String s) {

getTSLog().printWrite(s);

}

public static void close() {

getTSLog().close();

}

private static TSLog getTSLog() {

TSLog tsLog = tsLogCollection.get();

// 如果线程时第一次调用,新建立新文件并注册log

if (tsLog == null) {

tsLog = new TSLog(Thread.currentThread().getName() + "-log.txt");

tsLogCollection.set(tsLog);

}

return tsLog;

}

}

import java.io.FileNotFoundException;

import java.io.PrintWriter;

public class TSLog {

private PrintWriter writer;

public TSLog(String filename) {

try {

this.writer = new PrintWriter(filename);

} catch (FileNotFoundException e) {

}

}

public void printWrite(String s) {

writer.println(s);

}

public void close() {

writer.println("===========End of log===========");

writer.close();

}

}

public class ClientThread extends Thread {

public ClientThread(String name) {

super(name);

}

@Override

public void run() {

System.out.println(getName() + " Begin.");

for (int i = 0; i 

Log.println("i = " + i);

try {

Thread.sleep(100);

} catch (InterruptedException e) {

}

}

Log.close();

System.out.println(getName() + " End.");

}

public static void main(String[] args) {

new ClientThread("Alice").start();

new ClientThread("Bobby").start();

new ClientThread("Chris").start();

}

}

Active Object Pattern

Active Object

Pattern其实可以看作是多个多线程模式和多个设计模式组合成的一种更高级的模式,里面多个对象各司其职,共同协作。Active Object

Pattern里面使用到了Producer-Consumer Pattern、Thread-Per-Message Pattern、Future

Pattern和设计模式的Proxy Pattern、Command Pattern等。

Server端代码:

public interface ActiveObject {

public Result makeString(int count, char fillchar);

public void displayString(String string);

}

public class Proxy implements ActiveObject {

private SchedulerThread scheduler;

private Servant         servant;

public Proxy(SchedulerThread scheduler, Servant servant) {

this.scheduler = scheduler;

this.servant = servant;

}

@Override

public Result makeString(int count, char fillchar) {

FutureResult future = new FutureResult();

MakeStringRequest request = new MakeStringRequest(servant, future, count, fillchar);

this.scheduler.invoke(request);

return future;

}

@Override

public void displayString(String string) {

DisplayStringRequest request = new DisplayStringRequest(servant, string);

this.scheduler.invoke(request);

}

}

public class Servant implements ActiveObject {

@Override

public Result makeString(int count, char fillchar) {

char[] buffer = new char[count];

for (int i = 0; i 

buffer[i] = fillchar;

try {

Thread.sleep(500);

} catch (InterruptedException e) {

}

}

RealResult result = new RealResult(String.valueOf(buffer));

return result;

}

@Override

public void displayString(String string) {

System.out.println("displayString( " + string + " )");

try {

Thread.sleep(10);

} catch (InterruptedException e) {

}

}

}

public interface Result {

public String getResultValue();

}

public class FutureResult implements Result {

private Result  result;

private boolean isReady = false;

public synchronized void setResult(Result result) {

if (isReady) {

return;

}

this.result = result;

this.isReady = true;

notifyAll();

}

@Override

public synchronized String getResultValue() {

while (!isReady) {

try {

wait();

} catch (InterruptedException e) {

}

}

return result.getResultValue();

}

}

public class RealResult implements Result {

private String resultValue;

public RealResult(String resultValue) {

this.resultValue = resultValue;

}

@Override

public String getResultValue() {

return this.resultValue;

}

}

public abstract class MethodRequest {

protected final Servant      servant;

protected final FutureResult future;

public MethodRequest(Servant servant, FutureResult future) {

this.servant = servant;

this.future = future;

}

public abstract void execute();

}

public class MakeStringRequest extends MethodRequest {

private int  count;

private char fillchar;

public MakeStringRequest(Servant servant, FutureResult future, int count, char fillchar) {

super(servant, future);

this.count = count;

this.fillchar = fillchar;

}

@Override

public void execute() {

Result result = this.servant.makeString(count, fillchar);

future.setResult(result);

}

}

public class DisplayStringRequest extends MethodRequest {

private String string;

public DisplayStringRequest(Servant servant, String string) {

super(servant, null);

this.string = string;

}

@Override

public void execute() {

this.servant.displayString(string);

}

}

public class SchedulerThread extends Thread {

private ActivationQueue queue = new ActivationQueue();

public void invoke(MethodRequest request) {

this.queue.putRequest(request);

}

@Override

public void run() {

while (true) {

this.queue.takeRequest().execute();

}

}

}

package activeobject.server;

import java.util.LinkedList;

public class ActivationQueue {

private final LinkedList requestQueue = new LinkedList();

private final int                       queueSize    = 100;

public synchronized void putRequest(MethodRequest request) {

while (this.requestQueue.size() >= queueSize) {

try {

wait();

} catch (InterruptedException e) {

}

}

this.requestQueue.addLast(request);

notifyAll();

}

public synchronized MethodRequest takeRequest() {

while (this.requestQueue.size() == 0) {

try {

wait();

} catch (InterruptedException e) {

}

}

MethodRequest request = this.requestQueue.removeFirst();

notifyAll();

return request;

}

}

public class ActiveObjectFactory {

public static ActiveObject createActiveObjcet() {

Servant servant = new Servant();

SchedulerThread scheduler = new SchedulerThread();

Proxy proxy = new Proxy(scheduler, servant);

scheduler.start();

return proxy;

}

}

UML如下图:

e12e03884f0a4b2d4c3ab25d8352d05c.png

9866117

客户端代码:

import activeobject.server.ActiveObject;

public class DisplayClientThread extends Thread {

private ActiveObject activeObj;

public DisplayClientThread(String name, ActiveObject activeObj) {

super(name);

this.activeObj = activeObj;

}

@Override

public void run() {

int i = 0;

while (true) {

i++;

String string = getName() + " No." + i;

activeObj.displayString(string);

}

}

}

import activeobject.server.ActiveObject;

import activeobject.server.Result;

public class MakerClientThread extends Thread {

private final ActiveObject activeObj;

private final char         fillchar;

public MakerClientThread(String name, ActiveObject activeObj) {

super(name);

this.activeObj = activeObj;

this.fillchar = name.charAt(0);

}

@Override

public void run() {

int i = 0;

while (true) {

i++;

Result result = activeObj.makeString(i, fillchar);

try {

Thread.sleep(1000);

} catch (InterruptedException e) {

}

String resultValue = result.getResultValue();

System.out.println(Thread.currentThread().getName() + ":value = " + resultValue);

}

}

}

import activeobject.server.ActiveObject;

import activeobject.server.ActiveObjectFactory;

public class Main {

public static void main(String[] args) {

ActiveObject activeObj = ActiveObjectFactory.createActiveObjcet();

new MakerClientThread("Alice", activeObj).start();

new MakerClientThread("Bobby", activeObj).start();

new DisplayClientThread("Chris", activeObj).start();

}

}

本书浅显易懂的介绍了JAVA线程相关的设计模式,通过程序范例和UML图示来一一解说,书中代码的重要部分加了标注以使读者更加容易理解,再加上图文并茂,对于初学者还是程序设计高手来说,这都是一本学习和认识JAVA设计模式的一本好书。(注意,本资源附带书中源代码可供参考) 多线程与并发处理是程序设计好坏优劣的重要课题,本书通过浅显易懂的文字与实例来介绍Java线程相关的设计模式概念,并且通过实际的Java程序范例和 UML图示来一一解说,书中在代码的重要部分加上标注使读者更加容易解读,再配合众多的说明图解,无论对于初学者还是程序设计高手来说,这都是一本学习和认识设计模式非常难得的好书。 书中包含Java线程的介绍导读、12个重要的线程设计模式和全书总结以及丰富的附录内容。第一章相关线程设计模式的介绍,都举一反三使读者学习更有效。最后附上练习问题,让读者可以温故而知新,能快速地吸收书中的精华,书中最后附上练习问题解答,方便读者学习验证。 目录 漫谈UML UML 类图 类和层次结构的关系 接口与实现 聚合 访问控制 类间的关联性 顺序图 处理流程和对象间的协调 时序图 Introduction 1 Java语言的线程 Java语言的线程 何谓线程 明为追踪处理流程,实则追踪线程线程程序 多线程程序 Thread类的run方法和start方法 线程的启动 线程的启动(1)——利用Thread类的子类 线程的启动(2)——利用Runnable接口 线程的暂时停止 线程的共享互斥 synchronized方法 synchronized阻挡 线程的协调 wait set——线程的休息室 wait方法——把线程放入wait set notify方法——从wait set拿出线程 notifyAll方法——从wait set拿出所有线程 wait、notify、notifyAll是Object类的方法 线程的状态移转 跟线程有关的其他话题 重点回顾 练习问题 Introduction 2 多线程程序的评量标准 多线程程序的评量标准 安全性——不损坏对象 生存性——进行必要的处理 复用性——可再利用类 性能——能快速、大量进行处理 评量标准的总结 重点回顾 练习问题 第1章 Single Threaded Execution——能通过这座桥的,只有一个人 第2章 Immutable——想破坏它也没办法 第3章 Guarded Suspension——要等到我准备好喔 第4章 Balking——不需要的话,就算了吧 第5章 Producer-Consumer——我来做,你来用 第6章 Read-Write Lock——大家想看就看吧,不过看的时候不能写喔 第7章 read-Per-Message——这个工作交给你了 第8章 Worker Thread——等到工作来,来了就工作 第9章 Future——先给您这张提货单 第10章 Two-Phase Termination——快把玩具收拾好,去睡觉吧 第11章 Thread-Specific Storage——每个线程的保管箱 第12章 Active Object——接受异步消息的主动对象 总结 多线程程序设计的模式语言 附录A 练习问题的解答 附录B Java的内存模型 附录C Java线程的优先级 附录D 线程相关的主要API 附录E 参考文献
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值