您好,登錄后才能下訂單哦!
本篇文章給大家分享的是有關leetcode中怎么實現(xiàn)多線程,小編覺得挺實用的,因此分享給大家學習,希望大家閱讀完這篇文章后可以有所收獲,話不多說,跟著小編一起來看看吧。
現(xiàn)在有兩種線程,氧 oxygen 和氫 hydrogen,你的目標是組織這兩種線程來產生水分子。
存在一個屏障(barrier)使得每個線程必須等候直到一個完整水分子能夠被產生出來。
氫和氧線程會被分別給予 releaseHydrogen 和 releaseOxygen 方法來允許它們突破屏障。
這些線程應該三三成組突破屏障并能立即組合產生一個水分子。
你必須保證產生一個水分子所需線程的結合必須發(fā)生在下一個水分子產生之前。
換句話說:
如果一個氧線程到達屏障時沒有氫線程到達,它必須等候直到兩個氫線程到達。
如果一個氫線程到達屏障時沒有其它線程到達,它必須等候直到一個氧線程和另一個氫線程到達。
書寫滿足這些限制條件的氫、氧線程同步代碼。
示例 1:
輸入: "HOH"
輸出: "HHO"
解釋: "HOH" 和 "OHH" 依然都是有效解。
示例 2:輸入: "OOHHHH"
輸出: "HHOHHO"
解釋: "HOHHHO", "OHHHHO", "HHOHOH", "HOHHOH", "OHHHOH", "HHOOHH", "HOHOHH" 和 "OHHOHH" 依然都是有效解。
提示:
輸入字符串的總長將會是 3n, 1 ≤ n ≤ 50;
輸入字符串中的 “H” 總數(shù)將會是 2n 。
輸入字符串中的 “O” 總數(shù)將會是 n 。
package com.lau.multithread.h3o; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; /** * H2O 生成——解法一:傳統(tǒng)方式 現(xiàn)在有兩種線程,氧 oxygen 和氫 hydrogen,你的目標是組織這兩種線程來產生水分子。 存在一個屏障(barrier)使得每個線程必須等候直到一個完整水分子能夠被產生出來。 氫和氧線程會被分別給予 releaseHydrogen 和 releaseOxygen 方法來允許它們突破屏障。 這些線程應該三三成組突破屏障并能立即組合產生一個水分子。 你必須保證產生一個水分子所需線程的結合必須發(fā)生在下一個水分子產生之前。 換句話說: 如果一個氧線程到達屏障時沒有氫線程到達,它必須等候直到兩個氫線程到達。 如果一個氫線程到達屏障時沒有其它線程到達,它必須等候直到一個氧線程和另一個氫線程到達。 書寫滿足這些限制條件的氫、氧線程同步代碼。 示例 1: 輸入: "HOH" 輸出: "HHO" 解釋: "HOH" 和 "OHH" 依然都是有效解。 示例 2: 輸入: "OOHHHH" 輸出: "HHOHHO" 解釋: "HOHHHO", "OHHHHO", "HHOHOH", "HOHHOH", "OHHHOH", "HHOOHH", "HOHOHH" 和 "OHHOHH" 依然都是有效解。 提示: 輸入字符串的總長將會是 3n, 1 ≤ n ≤ 50; 輸入字符串中的 “H” 總數(shù)將會是 2n 。 輸入字符串中的 “O” 總數(shù)將會是 n 。 * */ class H2O{ private volatile int h = 0; private volatile int o = 0; public synchronized void printH(Runnable printH) { try { while(2 == this.h) { this.wait(); } printH.run(); this.h++; if(2 == this.h && 1 == this.o) { h = 0; o = 0; } this.notify(); } catch (Exception e) { e.printStackTrace(); } } public synchronized void printO(Runnable printO) { try { while(1 == this.o) { this.wait(); } printO.run(); this.o++; if(2 == this.h && 1 == this.o) { h = 0; o = 0; } this.notify(); } catch (Exception e) { e.printStackTrace(); } } } public class PrintH2ODemo { public static void main(String[] args) { ExecutorService threadPool = Executors.newFixedThreadPool(3); H2O h3o = new H2O(); for(int i = 0; i < 5; i++) { threadPool.execute(() -> h3o.printH(() -> System.out.print("H"))); threadPool.execute(() -> h3o.printH(() -> System.out.print("H"))); threadPool.execute(() -> h3o.printO(() -> System.out.print("O"))); } threadPool.shutdown(); } }
package com.lau.multithread.h3o; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.locks.Condition; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock; /** * H2O 生成——解法二:鎖方式 現(xiàn)在有兩種線程,氧 oxygen 和氫 hydrogen,你的目標是組織這兩種線程來產生水分子。 存在一個屏障(barrier)使得每個線程必須等候直到一個完整水分子能夠被產生出來。 氫和氧線程會被分別給予 releaseHydrogen 和 releaseOxygen 方法來允許它們突破屏障。 這些線程應該三三成組突破屏障并能立即組合產生一個水分子。 你必須保證產生一個水分子所需線程的結合必須發(fā)生在下一個水分子產生之前。 換句話說: 如果一個氧線程到達屏障時沒有氫線程到達,它必須等候直到兩個氫線程到達。 如果一個氫線程到達屏障時沒有其它線程到達,它必須等候直到一個氧線程和另一個氫線程到達。 書寫滿足這些限制條件的氫、氧線程同步代碼。 示例 1: 輸入: "HOH" 輸出: "HHO" 解釋: "HOH" 和 "OHH" 依然都是有效解。 示例 2: 輸入: "OOHHHH" 輸出: "HHOHHO" 解釋: "HOHHHO", "OHHHHO", "HHOHOH", "HOHHOH", "OHHHOH", "HHOOHH", "HOHOHH" 和 "OHHOHH" 依然都是有效解。 提示: 輸入字符串的總長將會是 3n, 1 ≤ n ≤ 50; 輸入字符串中的 “H” 總數(shù)將會是 2n 。 輸入字符串中的 “O” 總數(shù)將會是 n 。 * */ class H2O2{ private final Lock lock = new ReentrantLock(); final Condition condition = lock.newCondition(); private volatile int h = 0; private volatile int o = 0; public void printH(Runnable printH) { try { lock.lock(); while(2 == this.h) { condition.await(); } printH.run(); this.h++; if(2 == this.h && 1 == this.o) { h = 0; o = 0; } condition.signal(); } catch (Exception e) { e.printStackTrace(); } finally { lock.unlock(); } } public void printO(Runnable printO) { try { lock.lock(); while(1 == this.o) { condition.await(); } printO.run(); this.o++; if(2 == this.h && 1 == this.o) { h = 0; o = 0; } condition.signal(); } catch (Exception e) { e.printStackTrace(); } finally { lock.unlock(); } } } public class PrintH2ODemo2 { public static void main(String[] args) { ExecutorService threadPool = Executors.newFixedThreadPool(3); H2O2 h3o = new H2O2(); for(int i = 0; i < 5; i++) { threadPool.execute(() -> h3o.printH(() -> System.out.print("H"))); threadPool.execute(() -> h3o.printH(() -> System.out.print("H"))); threadPool.execute(() -> h3o.printO(() -> System.out.print("O"))); } threadPool.shutdown(); } }
package com.lau.multithread.h3o; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.Semaphore; import java.util.concurrent.locks.Condition; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock; /** * H2O 生成——解法三:信號量方式(HHO) 現(xiàn)在有兩種線程,氧 oxygen 和氫 hydrogen,你的目標是組織這兩種線程來產生水分子。 存在一個屏障(barrier)使得每個線程必須等候直到一個完整水分子能夠被產生出來。 氫和氧線程會被分別給予 releaseHydrogen 和 releaseOxygen 方法來允許它們突破屏障。 這些線程應該三三成組突破屏障并能立即組合產生一個水分子。 你必須保證產生一個水分子所需線程的結合必須發(fā)生在下一個水分子產生之前。 換句話說: 如果一個氧線程到達屏障時沒有氫線程到達,它必須等候直到兩個氫線程到達。 如果一個氫線程到達屏障時沒有其它線程到達,它必須等候直到一個氧線程和另一個氫線程到達。 書寫滿足這些限制條件的氫、氧線程同步代碼。 示例 1: 輸入: "HOH" 輸出: "HHO" 解釋: "HOH" 和 "OHH" 依然都是有效解。 示例 2: 輸入: "OOHHHH" 輸出: "HHOHHO" 解釋: "HOHHHO", "OHHHHO", "HHOHOH", "HOHHOH", "OHHHOH", "HHOOHH", "HOHOHH" 和 "OHHOHH" 依然都是有效解。 提示: 輸入字符串的總長將會是 3n, 1 ≤ n ≤ 50; 輸入字符串中的 “H” 總數(shù)將會是 2n 。 輸入字符串中的 “O” 總數(shù)將會是 n 。 * */ class H2O3{ private final Semaphore hsp = new Semaphore(2); private final Semaphore osp = new Semaphore(0); public void printH(Runnable printH) { try { hsp.acquire(); printH.run(); } catch (Exception e) { e.printStackTrace(); } finally { osp.release(); } } public void printO(Runnable printO) { try { osp.acquire(2); printO.run(); } catch (Exception e) { e.printStackTrace(); } finally { hsp.release(2); } } } public class PrintH2ODemo3 { public static void main(String[] args) { ExecutorService threadPool = Executors.newFixedThreadPool(3); H2O3 h3o = new H2O3(); for(int i = 0; i < 5; i++) { threadPool.execute(() -> h3o.printH(() -> System.out.print("H"))); threadPool.execute(() -> h3o.printH(() -> System.out.print("H"))); threadPool.execute(() -> h3o.printO(() -> System.out.print("O"))); } threadPool.shutdown(); } }
package com.lau.multithread.h3o; import java.util.concurrent.CyclicBarrier; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.Semaphore; import java.util.concurrent.locks.Condition; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock; /** * H2O 生成——解法四:信號量 + 屏障(帶最終觸發(fā)行為) 現(xiàn)在有兩種線程,氧 oxygen 和氫 hydrogen,你的目標是組織這兩種線程來產生水分子。 存在一個屏障(barrier)使得每個線程必須等候直到一個完整水分子能夠被產生出來。 氫和氧線程會被分別給予 releaseHydrogen 和 releaseOxygen 方法來允許它們突破屏障。 這些線程應該三三成組突破屏障并能立即組合產生一個水分子。 你必須保證產生一個水分子所需線程的結合必須發(fā)生在下一個水分子產生之前。 換句話說: 如果一個氧線程到達屏障時沒有氫線程到達,它必須等候直到兩個氫線程到達。 如果一個氫線程到達屏障時沒有其它線程到達,它必須等候直到一個氧線程和另一個氫線程到達。 書寫滿足這些限制條件的氫、氧線程同步代碼。 示例 1: 輸入: "HOH" 輸出: "HHO" 解釋: "HOH" 和 "OHH" 依然都是有效解。 示例 2: 輸入: "OOHHHH" 輸出: "HHOHHO" 解釋: "HOHHHO", "OHHHHO", "HHOHOH", "HOHHOH", "OHHHOH", "HHOOHH", "HOHOHH" 和 "OHHOHH" 依然都是有效解。 提示: 輸入字符串的總長將會是 3n, 1 ≤ n ≤ 50; 輸入字符串中的 “H” 總數(shù)將會是 2n 。 輸入字符串中的 “O” 總數(shù)將會是 n 。 * */ class H2O4{ private final Semaphore hsp = new Semaphore(2); private final Semaphore osp = new Semaphore(1); private final CyclicBarrier cb = new CyclicBarrier(3, ()-> { hsp.release(2); osp.release(1); }); public void printH(Runnable printH) { try { hsp.acquire(); printH.run(); cb.await(); } catch (Exception e) { e.printStackTrace(); } } public void printO(Runnable printO) { try { osp.acquire(); printO.run(); cb.await(); } catch (Exception e) { e.printStackTrace(); } } } public class PrintH2ODemo4 { public static void main(String[] args) { ExecutorService threadPool = Executors.newFixedThreadPool(3); H2O4 h3o = new H2O4(); for(int i = 0; i < 5; i++) { threadPool.execute(() -> h3o.printH(() -> System.out.print("H"))); threadPool.execute(() -> h3o.printH(() -> System.out.print("H"))); threadPool.execute(() -> h3o.printO(() -> System.out.print("O"))); } threadPool.shutdown(); } }
package com.lau.multithread.h3o; import java.util.concurrent.CyclicBarrier; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.Semaphore; import java.util.concurrent.locks.Condition; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock; /** * H2O 生成——解法四:信號量 + 屏障 現(xiàn)在有兩種線程,氧 oxygen 和氫 hydrogen,你的目標是組織這兩種線程來產生水分子。 存在一個屏障(barrier)使得每個線程必須等候直到一個完整水分子能夠被產生出來。 氫和氧線程會被分別給予 releaseHydrogen 和 releaseOxygen 方法來允許它們突破屏障。 這些線程應該三三成組突破屏障并能立即組合產生一個水分子。 你必須保證產生一個水分子所需線程的結合必須發(fā)生在下一個水分子產生之前。 換句話說: 如果一個氧線程到達屏障時沒有氫線程到達,它必須等候直到兩個氫線程到達。 如果一個氫線程到達屏障時沒有其它線程到達,它必須等候直到一個氧線程和另一個氫線程到達。 書寫滿足這些限制條件的氫、氧線程同步代碼。 示例 1: 輸入: "HOH" 輸出: "HHO" 解釋: "HOH" 和 "OHH" 依然都是有效解。 示例 2: 輸入: "OOHHHH" 輸出: "HHOHHO" 解釋: "HOHHHO", "OHHHHO", "HHOHOH", "HOHHOH", "OHHHOH", "HHOOHH", "HOHOHH" 和 "OHHOHH" 依然都是有效解。 提示: 輸入字符串的總長將會是 3n, 1 ≤ n ≤ 50; 輸入字符串中的 “H” 總數(shù)將會是 2n 。 輸入字符串中的 “O” 總數(shù)將會是 n 。 * */ class H2O5{ private final Semaphore hsp = new Semaphore(2); private final Semaphore osp = new Semaphore(1); private final CyclicBarrier cb = new CyclicBarrier(3); public void printH(Runnable printH) { try { hsp.acquire(); cb.await(); printH.run(); } catch (Exception e) { e.printStackTrace(); } finally { hsp.release(); } } public void printO(Runnable printO) { try { osp.acquire(); cb.await(); printO.run(); } catch (Exception e) { e.printStackTrace(); } finally { osp.release(); } } } public class PrintH2ODemo5 { public static void main(String[] args) { ExecutorService threadPool = Executors.newFixedThreadPool(3); H2O5 h3o = new H2O5(); for(int i = 0; i < 5; i++) { threadPool.execute(() -> h3o.printH(() -> System.out.print("H"))); threadPool.execute(() -> h3o.printH(() -> System.out.print("H"))); threadPool.execute(() -> h3o.printO(() -> System.out.print("O"))); } threadPool.shutdown(); } }
輸出:
//隨機 HOHOHHOHHOHHOHH
以上就是leetcode中怎么實現(xiàn)多線程,小編相信有部分知識點可能是我們日常工作會見到或用到的。希望你能通過這篇文章學到更多知識。更多詳情敬請關注億速云行業(yè)資訊頻道。
免責聲明:本站發(fā)布的內容(圖片、視頻和文字)以原創(chuàng)、轉載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權內容。