Java 代碼實例解析設計模式之監(jiān)聽者模式
代碼展示
Main:測試類
ObServer:每個被監(jiān)聽的對象實現(xiàn)該接口,重寫該方法,完成自己的業(yè)務
public interface ObServer { /** * 當某一個被監(jiān)控的對象發(fā)生變化時 * 所有實現(xiàn)該方法處理方法 */ void exceptionHandler(); }
Subject:監(jiān)聽者容器
public interface Subject { /** * 添加被觀察對象 */ void add(ObServer obServer); /** * 通知所有被觀察者完成自己的 exceptionHandler 方法 */ void notifyAllSubject(); }
SubjectHandler:監(jiān)聽者容器的實現(xiàn)類
public class SubjectHandler implements Subject { /** * 存放被監(jiān)聽對象 */ private static final List<ObServer> SUBJECTS = Collections.synchronizedList(new LinkedList<>()); @Override public void add(ObServer subject) { SUBJECTS.add(subject); } @Override public void notifyAllSubject() { SUBJECTS.forEach(ObServer::exceptionHandler); } }
Thread1、Thread2 測試對象
模擬兩個線程對數(shù)據(jù)庫操作,若Threa1執(zhí)行時出異常了,那么終止所有線程并對其回滾。
Threa1:
public class Thread1 implements ObServer, Runnable { @SneakyThrows @Override public void run() { System.out.println("thread1 run"); Thread.sleep(1000); System.out.println("t1 end"); } @SneakyThrows @Override public void exceptionHandler() { System.out.println("thread1 rollback....."); } }
Thread2:
public class Thread2 implements ObServer, Runnable { private static Thread CURRENT_THREAD; private static volatile boolean FLAG = false; @SneakyThrows @Override public void run() { CURRENT_THREAD = Thread.currentThread(); System.out.println("thread2 running"); int count = 0; while (!FLAG) { System.out.println(count); count++; } System.out.println("thread2 end"); } @SneakyThrows @Override public void exceptionHandler() { FLAG = true; CURRENT_THREAD.interrupt(); System.out.println("thread2 rollback....."); } }
測試Demo
public static void main(String[] args) throws InterruptedException { // 創(chuàng)建監(jiān)聽容器 Subject subject = new SubjectHandler(); Thread1 thread1 = new Thread1(); Thread2 thread2 = new Thread2(); subject.add(thread1); subject.add(thread2); CompletableFuture.supplyAsync(() -> { new Thread(thread1).start(); try { Thread.sleep(10); int a = 1 / 0; // 模擬線程1報錯 } catch (InterruptedException e) { e.printStackTrace(); } return true; }).exceptionally((error) -> { subject.notifyAllSubject(); return false; }); CompletableFuture.supplyAsync(() -> { new Thread(thread2).start(); return true; }).exceptionally((error) -> { subject.notifyAllSubject(); return false; }); // main thread await Thread.sleep(60 * 1000); }
測試結果
在 java.util 包下提供了Observable(監(jiān)聽容器)和 Observer接口(被監(jiān)聽者),用法跟我們完全一致,只需實現(xiàn)Observer的update方法,把每個Observer子類添加到監(jiān)聽容器中。
注意:在調用監(jiān)聽容器的通知所有servers時首先調用一下其setChanged方法
將changed變?yōu)閠rue(默認flase)
到此這篇關于Java 代碼實例解析設計模式之監(jiān)聽者模式的文章就介紹到這了,更多相關Java 設計模式內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
java組件commons-fileupload實現(xiàn)文件上傳、下載、在線打開
這篇文章主要介紹了java組件commons-fileupload實現(xiàn)文件上傳、下載、在線打開,具有一定的參考價值,感興趣的小伙伴們可以參考一下2016-10-10Java中的ArrayList、LinkedList、HashSet等容器詳解
這篇文章主要介紹了Java中的ArrayList、LinkedList、HashSet等容器詳解,集合表示一組對象,稱為其元素,有些集合允許重復元素,而另一些則不允許,有些是有序的,有些是無序的,需要的朋友可以參考下2023-08-08