觀察者設計模式觀察線程的生命週期
//使用觀察者設計模式觀察線程的生命週期 被觀察者是Thread
public abstract class ObservableRunnable implements Runnable {
final protected LifeCycleListener listener; //觀察者
public ObservableRunnable(final LifeCycleListener listener) {
this.listener = listener;
}
protected void notifyChange(final RunnableEvent event) {
listener.onEvent(event);
}
public enum RunnableState {
RUNNING, ERROR, DONE
}
public static class RunnableEvent {
private final RunnableState state;
private final Thread thread;//哪個線程
private final Throwable cause;//失敗的原因
public RunnableEvent(RunnableState state, Thread thread, Throwable cause) {
this.state = state;
this.thread = thread;
this.cause = cause;
}
public RunnableState getState() {
return state;
}
public Thread getThread() {
return thread;
}
public Throwable getCause() {
return cause;
}
}
}
public interface LifeCycleListener {//觀察者
void onEvent(ObservableRunnable.RunnableEvent event);
}
public class ThreadLifeCycleObserver implements LifeCycleListener {
private final Object LOCK = new Object();//共享數據的問題
public void concurrentQuery(List<String> ids) {
if (ids == null || ids.isEmpty())
return;
//把自己作爲observer給你
ids.stream().forEach(id -> new Thread(new ObservableRunnable(this) {
@Override
public void run() {
try {
notifyChange(new RunnableEvent
(RunnableState.RUNNING, Thread.currentThread(), null));
System.out.println("query for the id " + id);
Thread.sleep(1000L);
// int i = 1/0;
notifyChange
(new RunnableEvent(RunnableState.DONE, Thread.currentThread(), null));
} catch (Exception e) {
notifyChange
(new RunnableEvent(RunnableState.ERROR, Thread.currentThread(), e));
}
}
}, id).start());
}
@Override
public void onEvent(ObservableRunnable.RunnableEvent event) {
//把當前對象傳給ObservableRunnable,可能有多線程訪問問題
synchronized (LOCK) {//數據不一致,線程安全問題
System.out.println("The runnable [" + event.getThread().getName() + "]
data changed and state is [" + event.getState() + "]");
if (event.getCause() != null) {
//如果失敗 了可能再去嘗試等操作
System.out.println("The runnable [" + event.getThread().getName() +
"] process failed.");
event.getCause().printStackTrace();
}
}
}
}
public class ThreadLifeCycleClient {
public static void main(String[] args) {
//啓動2個線程去幹活
new ThreadLifeCycleObserver().concurrentQuery(Arrays.asList("1", "2"));
}
}
單線程執行設計模式,有一個門,始終只能一個人通過
public class Client {
public static void main(String[] args) {
Gate gate = new Gate();
User bj = new User("Baobao", "Beijing", gate);
User sh = new User("ShangLao", "ShangHai", gate);
User gz = new User("GuangLao", "GuangZhou", gate);
bj.start();
sh.start();
gz.start();
}
}
/**
* SharedResource共享資源
*/
public class Gate {//記錄一個大門(臨界值)的用戶信息,這裏沒有對門進行加鎖的方式實現的
private int counter = 0;
private String name = "Nobody";
private String address = "Nowhere";
/**
* 臨界值
*
* @param name
* @param address
*/
public synchronized void pass(String name, String address) {
this.counter++;
/*race*/
this.name = name;
this.address = address;
verify();
}
private void verify() {
//每次只有一個人通過
if (this.name.charAt(0) != this.address.charAt(0)) {
System.out.println("*******BROKEN********" + toString());
}
}
public synchronized String toString() {
return "No." + counter + ":" + name + "," + address;
}
}
public class User extends Thread {//有一個門,始終有一個人通過的場景
private final String myName;
private final String myAddress;
private final Gate gate;
public User(String myName, String myAddress, Gate gate) {
this.myName = myName;
this.myAddress = myAddress;
this.gate = gate;
}
@Override
public void run() {
System.out.println(myName + " BEGIN");
while (true) {
this.gate.pass(myName, myAddress);
}
}
}
多線程讀寫鎖分離設計模式
/**
* ReadWriteLock design pattern
* Reader-Writer design pattern
*/
public class ReadWritLockClient {
public static void main(String[] args) {
final SharedData sharedData = new SharedData(10);
new ReaderWorker(sharedData).start();
new ReaderWorker(sharedData).start();
new ReaderWorker(sharedData).start();
new ReaderWorker(sharedData).start();
new ReaderWorker(sharedData).start();
new WriterWorker(sharedData, "qwertyuiopasdfg").start();
new WriterWorker(sharedData, "QWERTYUIOPASDFG").start();
}
}
public class SharedData {
private final char[] buffer;
private final ReadWriteLock lock = new ReadWriteLock();
public SharedData(int size) {
this.buffer = new char[size];
for (int i = 0; i < size; i++) {
this.buffer[i] = '*';
}
}
public char[] read() throws InterruptedException {
try {
lock.readLock();
return this.doRead();
} finally {
lock.readUnlock();
}
}
public void write(char c) throws InterruptedException {
try {
lock.writeLock();
this.doWrite(c);
} finally {
lock.writeUnlock();
}
}
private void doWrite(char c) {
for (int i = 0; i < buffer.length; i++) {
buffer[i] = c;
slowly(10);
}
}
private char[] doRead() {
char[] newBuf = new char[buffer.length];
for (int i = 0; i < buffer.length; i++)
newBuf[i] = buffer[i];
slowly(50);
return newBuf;
}
private void slowly(int ms) {
try {
Thread.sleep(ms);
} catch (InterruptedException e) {
}
}
}
public class ReadWriteLock {
private int readingReaders = 0;
private int waitingReaders = 0;
private int writingWriters = 0;
private int waitingWriters = 0;
//實現寫鎖優先
private boolean preferWriter = true;
public ReadWriteLock() {
this(true);
}
public ReadWriteLock(boolean preferWriter) {
this.preferWriter = preferWriter;
}
//獲取對象的鎖,這裏用了try finally 同時用鎖的時候也是要try finally的
public synchronized void readLock() throws InterruptedException {
this.waitingReaders++;
try {
while (writingWriters > 0 || (preferWriter && waitingWriters > 0)) {
this.wait();
}
this.readingReaders++;
} finally {
this.waitingReaders--;
}
}
public synchronized void readUnlock() {
this.readingReaders--;
this.notifyAll();
}
public synchronized void writeLock() throws InterruptedException {
this.waitingWriters++;
try {
while (readingReaders > 0 || writingWriters > 0) {
this.wait();
}
this.writingWriters++;
} finally {
this.waitingWriters--;
}
}
public synchronized void writeUnlock() {
this.writingWriters--;
this.notifyAll();
}
}
public class ReaderWorker extends Thread {
private final SharedData data;
public ReaderWorker(SharedData data) {
this.data = data;
}
@Override
public void run() {
try {
while (true) {
char[] readBuf = data.read();
System.out.println(Thread.currentThread().getName() + " reads " + String.valueOf(readBuf));
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public class WriterWorker extends Thread {
private static final Random random = new Random(System.currentTimeMillis());
private final SharedData data;
private final String filler;
private int index = 0;
public WriterWorker(SharedData data, String filler) {
this.data = data;
this.filler = filler;
}
@Override
public void run() {
try {
while (true) {
char c = nextChar();
data.write(c);
Thread.sleep(random.nextInt(1000));
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
private char nextChar() {
char c = filler.charAt(index);
index++;
if (index >= filler.length())
index = 0;
return c;
}
}
多線程 Future 設計模式
public interface FutureTask<T> {
T call();
}
/** 想想UML類圖
* Future -> 代表的是未來的一個憑據
* FutureTask -> 將你的調用邏輯進行了隔離
* FutureService -> 橋接 Future和 FutureTask
*/
public class SyncInvoker {
public static void main(String[] args) throws InterruptedException {
/*String result = get();//同步調用
System.out.println(result);*/
//思路:返回的Future,具體類AsynFuture,任務FutureTask,將他們橋接起來的FutureService 畫出uml圖分析一下
FutureService futureService = new FutureService();
Future<String> future = futureService.submit(() -> {
try {
Thread.sleep(10000l);
} catch (InterruptedException e) {
e.printStackTrace();
}
return "FINISH";
}, System.out::println);
//這裏沒阻塞
System.out.println("===========");
System.out.println(" do other thing.");
Thread.sleep(1000);
System.out.println("===========");
// //這裏阻塞了
// String result = future.get();
// System.out.println(result);
}
private static String get()
throws InterruptedException {
Thread.sleep(10000l);
return "FINISH";
}
}
public class FutureService {//將Future和FutureTask橋接起來
public <T> Future<T> submit(final FutureTask<T> task) {
//異步的Future實現 ,調用asynFuture的方法可能是不一樣的線程
AsynFuture<T> asynFuture = new AsynFuture<>();
new Thread(() -> {
T result = task.call();
asynFuture.done(result);
}).start();
return asynFuture;
}
//執行完後就Consumer
public <T> Future<T> submit(final FutureTask<T> task, final Consumer<T> consumer) {
AsynFuture<T> asynFuture = new AsynFuture<>();
new Thread(() -> {
T result = task.call();
asynFuture.done(result);
//執行後就立馬通知了,減少時間誤差
consumer.accept(result);
}).start();
return asynFuture;
}
}
public interface Future<T> {
T get() throws InterruptedException;
}
public class AsynFuture<T> implements Future<T> {
private volatile boolean done = false;
private T result;
public void done(T result) {
synchronized (this) {
this.result = result;
this.done = true;
this.notifyAll();//done和get不一定是同一個線程
}
}
@Override
public T get() throws InterruptedException {
synchronized (this) {
while (!done) {
//阻塞的,考慮多線程
this.wait();
}
}
return result;
}
}
多線程Count Down設計模式
public class CustomCountDownClient {
private static final Random random = new Random(System.currentTimeMillis());
public static void main(String[] args) throws InterruptedException {
final CountDown latch = new CountDown(5);
System.out.println("準備多線程處理任務.");
//The first phase.
IntStream.rangeClosed(1, 5).forEach(i ->
new Thread(() -> {
System.out.println(Thread.currentThread().getName() + " is working.");
try {
Thread.sleep(random.nextInt(1000));
} catch (InterruptedException e) {
e.printStackTrace();
}
latch.down();
}, String.valueOf(i)).start()
);
latch.await();
//The second phase.
System.out.println("多線程任務全部結束,準備第二階段任務");
System.out.println("............");
System.out.println("FINISH");
}
}
public class CountDown {
private final int total;
private int counter = 0;
public CountDown(int total) {
this.total = total;
}
public void down() {
synchronized (this) {
this.counter++;
this.notifyAll();
}
}
public void await() throws InterruptedException {
synchronized (this) {
while (counter != total) {
this.wait();
}
}
}
}
public class JDKCountDown {
private static final Random random = new Random(System.currentTimeMillis());
public static void main(String[] args) throws InterruptedException {
//底層是AbstractQueuedSynchronizer實現的
final CountDownLatch latch = new CountDownLatch(5);
System.out.println("準備多線程處理任務.");
//The first phase.
IntStream.rangeClosed(1, 5).forEach(i ->
new Thread(() -> {
System.out.println(Thread.currentThread().getName() + " is working.");
try {
Thread.sleep(random.nextInt(1000));
} catch (InterruptedException e) {
e.printStackTrace();
}
latch.countDown();
}, String.valueOf(i)).start()
);
latch.await();
//The second phase.
System.out.println("多線程任務全部結束,準備第二階段任務");
System.out.println("............");
System.out.println("FINISH");
}
}
多線程Active Objects設計模式
…