??xml version="1.0" encoding="utf-8" standalone="yes"?>日韩免费久久,天堂av在线,欧美一级二级在线观看http://www.aygfsteel.com/jesson2005/category/21672.htmlN文hQ乃市井一俗h也,ȝ卷书Q跨江河千里Q故甛_一游; 一两滴辛酸Q三四年学业Q五六点_墨Q七八笔买卖Q九十道人情?/description>zh-cnWed, 18 Apr 2007 04:28:51 GMTWed, 18 Apr 2007 04:28:51 GMT60Design Pattern: Thread-Specific Storage 模式http://www.aygfsteel.com/jesson2005/articles/111204.html张金?/dc:creator>张金?/author>Tue, 17 Apr 2007 02:59:00 GMThttp://www.aygfsteel.com/jesson2005/articles/111204.htmlhttp://www.aygfsteel.com/jesson2005/comments/111204.htmlhttp://www.aygfsteel.com/jesson2005/articles/111204.html#Feedback0http://www.aygfsteel.com/jesson2005/comments/commentRss/111204.htmlhttp://www.aygfsteel.com/jesson2005/services/trackbacks/111204.html
Thread-Specific Storage模式嘗試從另一個角度來解釋多執行緒q資源的問,其思考點很簡單,即然q資源這麼困難Q那麼就乾脆不要qQ何不為每個執行緒創造一個資源的複本Q將每一個執行緒存取資料的行為加以隔離,其實珄ҎQ就是予每一個執行緒一個特定空間來保管該執行緒所獨n的資源,也因此而稱之為 Thread- Specific Storage模式?br>
在Java中可以用java.lang.ThreadLocal來實N個模式,這個類別是?.2之後開始提供Q不過先來看看,如何自行實現一個簡單的ThreadLocal別Q?br>
  • ThreadLocal.java
import java.util.*;

public class ThreadLocal {
private Map storage =
Collections.synchronizedMap(new HashMap());

public Object get() {
Thread current = Thread.currentThread();
Object o = storage.get(current);

if(o == null && !storage.containsKey(current)) {
o = initialValue();
storage.put(current, o);
}

return o;
}

public void set(Object o) {
storage.put(Thread.currentThread(), o);
}

public Object initialValue() {
return null;
}
}

可以看到E式中用執行緒本n作為key|並將所獲得的資源放在Map物g中,如果W一ơ用get()Q也配置一個空間埯R,?initialValue()可以用來a定什麼樣的初D先儲存在這個空間中Q在這邊先簡單的a定為null?br>
珑֜假設有一個原先在單執行緒環境下的資源SomeResourceQ現在考慮要該其在多執行緒環境下用,若不惌慮複雜的執行緒q互斥問題Q此時可以用ThreadLocal別來用SomeResourceQ例如:
  • Resource.java
public class Resource {
private static final ThreadLocal threadLocal =
new ThreadLocal();

public static SomeResource getResource() {
SomeResource resource =
(SomeResource) threadLocal.get();

if(resource == null) {
resource = new SomeResource();
threadLocal.set(resource);
}

return resource;
}
}

上面所實作的ThreadLocal別只是一個簡單的C範Q您可以使用java.lang.ThreadLocal來實現Thread- Specific Storage模式Q以獲得更好的效能,在這邊單的示一個LogE式Q它可以a錄每個執行緒的活動,所使用的是 java.util.logging中的別Q?br>
  • SimpleThreadLogger.java
import java.io.*;
import java.util.logging.*;

public class SimpleThreadLogger {
private static final ThreadLocal threadLocal =
new ThreadLocal();

public static void log(String msg) {
getThreadLogger().log(Level.INFO, msg);
}

private static Logger getThreadLogger() {
Logger logger = (Logger) threadLocal.get();

if(logger == null) {
try {
logger = Logger.getLogger(
Thread.currentThread().getName());
// Logger 預設是在L台?br> // 我們加入一個檔案出的Handler
// 它會輸出XML的記錄文?br> logger.addHandler(
new FileHandler(
Thread.currentThread().getName()
+ ".log"));
}
catch(IOException e) {}

threadLocal.set(logger);
}

return logger;
}
}

可以使用下面這個程式來測試Q?br>
  • LoggerTest.java
public class LoggerTest {
public static void main(String[] args) {
new TestThread("thread1").start();
new TestThread("thread2").start();
new TestThread("thread3").start();
}
}

class TestThread extends Thread {
public TestThread(String name) {
super(name);
}

public void run() {
for(int i = 0; i < 10; i++) {
SimpleThreadLogger.log(getName() +
": message " + i);
try {
Thread.sleep(1000);
}
catch(Exception e) {
SimpleThreadLogger.log(e.toString());
}
}
}
}

埯LoggerTest可以在主控台上看到出,並可以在同一目錄下找C個log檔,分別a錄了三個執行緒的活動,透過 ThreadLocalQ不用撰寫複雜的埯R共用互斥邏輯?br>
Thread-Specific Storage模式的意之一Q就是「有時不q是好的」,如果q會產生危險,那就不要qQ當Ӟ這種方式所犧牲掉的是I間Q您必須為每一個執行緒保留它們獨立的I間Q這是一E以I間換取時間與安全性的Ҏ?

]]>
Design Pattern: Read-Write-Lock 模式http://www.aygfsteel.com/jesson2005/articles/111201.html张金?/dc:creator>张金?/author>Tue, 17 Apr 2007 02:58:00 GMThttp://www.aygfsteel.com/jesson2005/articles/111201.htmlhttp://www.aygfsteel.com/jesson2005/comments/111201.htmlhttp://www.aygfsteel.com/jesson2005/articles/111201.html#Feedback0http://www.aygfsteel.com/jesson2005/comments/commentRss/111201.htmlhttp://www.aygfsteel.com/jesson2005/services/trackbacks/111201.html
讀取寫入的同步問題向來是難解的問題之一Q有qր可行的作法Q例如若有寫入的動作時,則讀取者以唯讀模式開啟Q或是如果有開啟資料檔的動作時,無論是讀取或是寫入,後一個開啟檔案的客戶都一律以唯讀模式開啟Q還有最乾脆的作法,是這個問由客戶決定Q在開啟檔案時若已有其他人開啟中Q則提供達R讓客戶決定要不要以唯讀模式開啟Q通常這個作法是提供i檔案的擁有者用?br>
Read-Write-Lock 模式提供i被讀取或寫入的資料「一把鎖」,在讀取或寫入時都必須先取得這把鎖,讀取的客戶可以同時共同這把鎖,而寫入的客戶也可以共用這把鎖,但讀取不可與寫入q一把鎖Q如果嘗試取得鎖時發N已經被另一方取得,則等待直到鎖被釋放並重新取得它?br>
下圖讀取者讀取資料時的Sequence DiagramCZQ?
Read-Write-Lock

珑֜假設讀取者已E取得鎖Q而寫入者試圖進行寫入Q它也試圖先取得鎖定Q但發現鎖已E被讀取的一Ҏ有,於是先進入{待Q直到讀取的一方解除鎖定為止:
Read-Write-Lock

一個簡單的JavaE式例子如下所C:
 public void readData() {
    lock.readLock();
    doRead();
    lock.readUnLock();
 }

 public void writeData() {
    lock.writeLock();
    doWrite();
    lock.writeUnLock();
 }
 

而最主要的關鍵還是在於鎖的實現,在Java中可以用wait()、notify()來實現,實現的片D如下:
 private boolean writerFirst = true; // 寫入優先
 
 public synchronized void readLock() {
    try {
        while(writingWriters > 0 ||
                   (writerFirst && waitingWriters > 0)) {
            wait();
        }
    }
    catch(InterruptedException) {
    }

    readingReaders++;
 }
 
 public synchronized void readUnLock() {
    readingReaders--;
    writerFirst = true;
    notifyAll();
 }
 
 public synchronized void writeLock() {
    waitingWriters++
    try {
        while(readingReaders > 0 || writingWriters > 0) {
            wait();
        }
    }
    catch(InterruptedException) {
    }
    finally {
        waitingWriters--;
    }

    writingWriters++;
 }
 
 public synchronized void writeUnLock() {
    writingWriters--;
    writerFirst = false;
    notifyAll();
 }
 

其中writerFirst是寫入優先的旗標Q它Z只要有寫入的埯R在{待時,在解除鎖定的時候,可以優先由寫入執行緒取得鎖定Q以Z讀取者讀取到的資料可以是最新的Q但~點是寫入的動作很ȝ時,讀取者必須等待的會增多,相反的若a定取優先,則讀取時的回應性會增高Q但資料更新的速率會下降Q實際用時要偏好哪一方,必須視應用的場合而定?

]]>
Design Pattern: Two-phase Termination 模式http://www.aygfsteel.com/jesson2005/articles/111202.html张金?/dc:creator>张金?/author>Tue, 17 Apr 2007 02:58:00 GMThttp://www.aygfsteel.com/jesson2005/articles/111202.htmlhttp://www.aygfsteel.com/jesson2005/comments/111202.htmlhttp://www.aygfsteel.com/jesson2005/articles/111202.html#Feedback0http://www.aygfsteel.com/jesson2005/comments/commentRss/111202.htmlhttp://www.aygfsteel.com/jesson2005/services/trackbacks/111202.html
以Java的Threadi止而言Q不您直接用stop()Ҏ來終止執行緒Qstop()Ҏ會丟出ThreadDeath例外弯埯R終止,即埯R正在運作階D|埯至synchronized區Q如果您要終止執行緒Q徏議自行實作,例如Q?br>
  public class SomeThread extends Thread {
    private boolean isTerminated = false;

    public void terminate() {
        isTerminated = true;
    }

    public void run() {
        while(!isTerminated) {
            // ... some statements
        }
    }
 }
 
考慮到有時執行緒可能會執行至sleep()或wait()而進入Not Runnable狀態,使用上面的方法可能會廉i止的請求,因而可以在要求i止時再呼叫interrupt()ҎQ這會丟出 InterruptedExceptionQ而得執行緒從Not Runnable狀態中離開Q因此可以改變一下程式:
 public class SomeThread extends Thread {
    private boolean isTerminated = false;

    public void terminate() {
        isTerminated = true;
        interrupt();
    }

    public void run() {
        try {
            while(!isTerminated) {
                // ... some statements
            }
        }
        catch(InterruptedException e) {
        }
    }
 }
 
在發Z止請求之後,如果埯R是在Not Runnable狀態,會丟出InterruptedExceptionQ如果這個例外沒有先被捕捉,會被run()中的catch InterruptedException捕捉Q也是說會直接離開whileq圈Q因而如果您在發出終止請求後Q要求先埯完這一個週期的工作,您要先捕捉這個例外,若不用完成這一個週期的工作,則不用捕捉這個例外,要如何作取決於您的程式?br>
如果埯R要完成這一個週期的工作,在下一個週期開始之前檢查旗標Q這時它的i果是falseQ所以離開whileq圈Q這時候您可以進行一些善後工作,這個可以寫在finally區塊中Q例如:
 public class SomeThread extends Thread {
    private boolean isContinue = false;

    public void terminate() {
        isTerminated = true;
        interrupt();
    }

    private void doWorkBeforeShutdown() {
        // .... do some work before shutdown
    }

    public void run() {
        try {
            while(!_isTerminated) {
                // ... some statements
            }
        }
        catch(InterruptedException e) {
        }
        finally {
            doWorkBeforeShutdown();
        }
    }
 }
 
上面這個程式大致上是Two-phase Termination模式的架構,另外如果您的埯R還服務著其它的物gQ則在送出i止請求到完全終止之前,應該停止服務其它物gQ您可以讓其它物件要求服務之前,先查詢執行緒是否已被要求i止Q這可以藉由提供一個方法來達到Q?br>
 public class SomeThread extends Thread {
    private boolean isTerminated = false;

    public void terminate() {
        isTerminated = true;
        interrupt();
    }

    public boolean isTerminated() {
        return _isTerminated;
    }

    private void doWorkBeforeShutdown() {
        // .... do some work before shutdown
    }

    public void run() {
        try {
            while(!_isTerminated) {
                // ... some statements
            }
        }
        catch(InterruptedException e) {
        }
        finally {
            doWorkBeforeShutdown();
        }
    }
 }


]]>
Design Pattern: Future 模式http://www.aygfsteel.com/jesson2005/articles/111199.html张金?/dc:creator>张金?/author>Tue, 17 Apr 2007 02:57:00 GMThttp://www.aygfsteel.com/jesson2005/articles/111199.htmlhttp://www.aygfsteel.com/jesson2005/comments/111199.htmlhttp://www.aygfsteel.com/jesson2005/articles/111199.html#Feedback0http://www.aygfsteel.com/jesson2005/comments/commentRss/111199.htmlhttp://www.aygfsteel.com/jesson2005/services/trackbacks/111199.htmlProxy 模式 ?Thread-Per-Message 模式 的結合,在Proxy模式中,用一個Proxy來代替真正的目標QSubjectQ生成,目標的生成可能是L的,例如在開啟一個內嵌圖片的文g中,希望E式能儘快完成開啟文件的動作Q並示一個可接受的畫面使用者看Q在還不需要看到圖片的頁面中先使用Proxy代替真正的圖片載入,只有在真正需要看到圖片時Q才由Proxy物g載入真正的圖片?br>
考慮這樣一個情況,使用者可能快速翻頁瀏覽文g中,而圖片檔案很大,如此在瀏覽到有圖片的頁數時Q就會導致圖片的載入Q因而造成使用者瀏覽文g時會有停頓的現象Q所以我們希望在文g開啟之後Q仍有一個背景作業持U載入圖片,如此使用者在快速瀏覽頁面時,所造成的停頓可以獲得改善?br>
Future模式在請求發生時Q會先產生一個Future物gi發求的客戶Q它的作用就像是Proxy物gQ而同時間Q真正的目標物g之生成,׃個新的執行緒持續進行Q即Thread-Per-MessageQ,真正的目標物件生成之後,之a定至Future之中Q而當客戶端真正需要目標物件時Q目標物件也已經準備好,可以讓客戶提取用?

Future

一個簡單的JavaE式片段C範可能像是這樣Q?br>
....
 public Future request() {
    final Future future = new Future();

    new Thread() {
        public void run() {
            // 下面這個動作可能是耗時?/span>
            RealSubject subject = new RealSubject();
            future.setRealSubject(subject);
        }
    }.start();

    return future;
 }


]]>
Design Pattern: Producer Consumer 模式http://www.aygfsteel.com/jesson2005/articles/111195.html张金?/dc:creator>张金?/author>Tue, 17 Apr 2007 02:56:00 GMThttp://www.aygfsteel.com/jesson2005/articles/111195.htmlhttp://www.aygfsteel.com/jesson2005/comments/111195.htmlhttp://www.aygfsteel.com/jesson2005/articles/111195.html#Feedback0http://www.aygfsteel.com/jesson2005/comments/commentRss/111195.htmlhttp://www.aygfsteel.com/jesson2005/services/trackbacks/111195.htmlGuarded Suspension 模式 是類似的Q只不過Guarded Suspension模式並不限制R衝區的長度,Producer Consumer模式假設所生產的產品放|在一個長度有限制的m衝區Q就像是一個產品桌Q它可以擺放的空間是有限的)Q如果m衝區滿了Q則生產者必須停止繼U將產品攑ֈR衝區中,直到消費者取C產品而有了空間,而如果m衝區中沒有產品,當然消費者必須等待,直到有新的產品放到m衝區中?

一個簡單的 UML 順序圖如下所C:
ProducerConsumer
單來說QProducer Consumer模式像是加上了雙重防護與等待的Guarded Suspension模式Q而它的兩個防譯{待的條件洽好相反,一個用Java實現的簡單流E架構如下:
  • ProductTable.java
import java.util.LinkedList;

public class ProductTable {
private LinkedList products = new LinkedList();

public synchronized void addProduct(Product product) {
while(products.size() >= 2) { // 定w限制?2
try {
wait();
}
catch(InterruptedException e) {}
}

products.addLast(product);
notifyAll();
}

public synchronized Product getProduct() {
while(products.size() <= 0) {
try {
wait();
}
catch(InterruptedException e) {}
}

Product product = (Product) products.removeFirst();
notifyAll();

return product;
}
}

以下舉一個最單的:生產者每ơ生產一個整怸攄在桌子上Q而消費者消耗整數,桌子上一ơ只能放|一個整數,如果桌子上已有整數,則生產者等待消費者將整數消耗並通知生產者生產下一個整數,如果桌子上沒有整數,則消費者等待生產者生產整怸通知消費者可以消耗整數?br>
  • Producer.java
public class Producer extends Thread {
private ProductTable productTable;

public Producer(ProductTable productTable) {
this.productTable = productTable;
}

public void run() {
System.out.println("Produce integer......");
for(int product = 1; product <= 10; product++) {
try {
// wait for a random time
Thread.sleep((int) Math.random() * 3000);
}
catch(InterruptedException e) {
e.printStackTrace();
}
productTable.setIntProduct(product);
}
}
}

  • Consumer.java
public class Consumer extends Thread {
private ProductTable productTable;

public Consumer(ProductTable productTable) {
this.productTable = productTable;
}

public void run() {
for(int i = 1; i <= 10; i++) {
try {
// wait for a random time
Thread.sleep((int) (Math.random() * 3000));
}
catch(InterruptedException e) {
e.printStackTrace();
}
productTable.getProductInt();
}
}
}

 

生產者將產品放至桌上Q而消費者將產品從桌上取赎ͼ所以桌子是個維h否讓被放|或消耗產品的地方Q由它來決定誰必須等待與通知Q?
  • ProductTable.java
public class ProductTable {
private int productInt = -1; // -1 for no product

public synchronized void setIntProduct(int product) {
if(productInt != -1) {
try {
wait();
}
catch(InterruptedException e) {
e.printStackTrace();
}
}

productInt = product;
System.out.println("set (" + product + ")");
notify();
}

public synchronized int getProductInt() {
if(productInt == -1) {
try {
wait();
}
catch(InterruptedException e) {
e.printStackTrace();
}
}

int p = productInt;
System.out.println("Get (" + productInt + ")");
productInt = -1;

notify();

return p;
}
}

生產者會生產10個整數,而消費者會消?0個整數,由於桌上只能攄一個整數,所以每生產一個就消耗一個?br>

]]>
Design Pattern: Worker Thread 模式http://www.aygfsteel.com/jesson2005/articles/111196.html张金?/dc:creator>张金?/author>Tue, 17 Apr 2007 02:56:00 GMThttp://www.aygfsteel.com/jesson2005/articles/111196.htmlhttp://www.aygfsteel.com/jesson2005/comments/111196.htmlhttp://www.aygfsteel.com/jesson2005/articles/111196.html#Feedback0http://www.aygfsteel.com/jesson2005/comments/commentRss/111196.htmlhttp://www.aygfsteel.com/jesson2005/services/trackbacks/111196.htmlProducer Consumer 模式Q在Request的行Z像是 Command 模式?br>
Producer Consumer模式注於Product的生產與消費Q至於Product被消L是作何處理,則不在它的討論範圍之中?
WorkerThread

如果您的Product是一個RequestQ消費者取得Request之後Q執行Request中指定的請求ҎQ也是使用Command模式Q並且您的RequestR衝區還管理了ConsumerQ就有Worker Thread模式的意思了?br>
WorkerThread

在Sequence Diagram上,可以看出Worker Thread同時展現了Producer Consumer模式與Command模式Q?br>
WorkThread
利用Java實現的一個Channel如下所C:
  • Channel.java
import java.util.LinkedList; 

public class Channel {
private LinkedList requests;
private WorkerThread[] workerThreads;

public Channel(int threadNumber) {
requests = new LinkedList();
workerThreads = new WorkerThread[threadNumber];
for(int i = 0; i < workerThreads.size(); i++) {
workerThreads[i] = new WorkerThread();
workerThreads[i].start();
}
}

public synchronized void putRequest(Request request) {
while(requests.size() >= 2) { // 定w限制?2
try {
wait();
}
catch(InterruptedException e) {}
}

requests.addLast(request);
notifyAll();
}

public synchronized Request getProduct() {
while(requests.size() <= 0) {
try {
wait();
}
catch(InterruptedException e) {}
}

Request request = (Request) requests.removeFirst();
notifyAll();

return request;
}
}

Request與WorkerThread之間採的Command模式Q?br>
  • Request.java
public class Request() { 
// ....

public void execute() {
// do some work....
}
}

  • WorkerThread.java
public class WorkerThread extends Thread { 
// ...

public void run() {
while(true) {
Request request = channel.getRequest();
request.execute();
}
}
}

pZQWorkerThread是有請求來了就作,如果沒有請求Q則所有的WorkerThreadq待,直到有新的工作進來而通知它們,取得請求的WorkerThread要作的工作,q接定在execute()中?



]]>
Design Pattern: Thread-Per-Message 模式http://www.aygfsteel.com/jesson2005/articles/111198.html张金?/dc:creator>张金?/author>Tue, 17 Apr 2007 02:56:00 GMThttp://www.aygfsteel.com/jesson2005/articles/111198.htmlhttp://www.aygfsteel.com/jesson2005/comments/111198.htmlhttp://www.aygfsteel.com/jesson2005/articles/111198.html#Feedback0http://www.aygfsteel.com/jesson2005/comments/commentRss/111198.htmlhttp://www.aygfsteel.com/jesson2005/services/trackbacks/111198.html
 menuOpenFile.addActionListener(
    new ActionListener() {
        public void actionPerformed(ActionEvent e) {
            openFile();
        }
    }
 );
 

openFile()Ҏ中主要是開啟檔案、一行一行讀檔案文字並設定文字至文字區域中Q這樣a計基本上沒有什麼問,例如果您的文件內容很P在讀檔必須花M些時間時Q您會發珑֜檔案讀取完畢前Q您的視H會有明的停頓現象?br>
 menuOpenFile.addActionListener(
    new ActionListener() {
        public void actionPerformed(ActionEvent e) {
            new Thread(new Runnable(){
                public void run() {
                    openFile();
                }
            }).start();
        }
    }
 );
 
在事件發生之後,您將檔案處理的動作交׃個執行緒d行,而事件處理執行緒直接回到回應事g的狀態,如此卛_解決視窗在載入檔案時的停頓?br>
單的說QThread-Per-Message模式是在某個請求發生時Q新增一個執行緒來執行該請求Q而主埯R繼U往下執行,除了上面的載入檔案例子之外,像是進行搜尋、字串轉換之需要一些時間來埯的工作時Q用Thread-Per-Message模式都可以提高主埯R(界面Q的回應性?br>


]]>
Design Pattern: Guarded Suspension 模式http://www.aygfsteel.com/jesson2005/articles/111194.html张金?/dc:creator>张金?/author>Tue, 17 Apr 2007 02:54:00 GMThttp://www.aygfsteel.com/jesson2005/articles/111194.htmlhttp://www.aygfsteel.com/jesson2005/comments/111194.htmlhttp://www.aygfsteel.com/jesson2005/articles/111194.html#Feedback0http://www.aygfsteel.com/jesson2005/comments/commentRss/111194.htmlhttp://www.aygfsteel.com/jesson2005/services/trackbacks/111194.html
關於這個描q的一個簡?UML 順序圖如下所C:
GuardedSuspension

首先要考慮刎ͼR衝區會同時被兩個以上的埯R進行存取Q即伺服器的請求處理埯R與客戶端執行緒Q所以必須對R衝區進行防護?br>
再來是當R衝區中沒有請求時Q伺服器必須{待直到被通知有新的請求?br>
Guarded Suspension模式關注的是埯的流E架構,以Java來實N個架構的話如下所C:
  • RequestQueue.java
public class RequestQueue {
private java.util.LinkedList queue;
public RequestQueue() {
queue = new java.util.LinkedList();
}

public synchronized Request getRequest() {
while(queue.size() <= 0) {
try {
wait();
}
catch(InterruptedException e) {}
}
return (Request) queue.removeFirst();
}

public synchronized void putRequest(Request request) {
queue.addLast(request);
notifyAll();
}
}

一個例子是多h聊天伺服器,請求可能只是一個客戶端送出的聊天訊息,聊天a息會先存至R衝區中,伺服器會不斷的從R衝區中取天訊息並發客戶端,如果R衝區中沒有新a息Q則伺服器就進入{待Q直到有一個客戶端發出聊天a息並存入m衝區中,此時伺服器再度被通知Q然後再度取息並進行發送?br>

]]>
վ֩ģ壺 ɫ| ˲| ˳| | ʲ| | | | ½| ̨ɽ| | | | ĵ| ף| | | ƽ| Ļ| ƽ| | | °Ͷ| Է| | | | | ɽ| | ӽ| | | | | ɽ| | Ȫ| | | |