91超碰碰碰碰久久久久久综合_超碰av人澡人澡人澡人澡人掠_国产黄大片在线观看画质优化_txt小说免费全本

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

leetcode中怎么利用多線程交替打印FooBar

發布時間:2021-06-22 16:56:07 來源:億速云 閱讀:229 作者:Leah 欄目:編程語言

這篇文章將為大家詳細講解有關leetcode中怎么利用多線程交替打印FooBar,文章內容質量較高,因此小編分享給大家做個參考,希望大家閱讀完這篇文章后對相關知識有一定的了解。

我們提供一個類:

class FooBar {
  public void foo() {
    for (int i = 0; i < n; i++) {
      print("foo");
    }
  }

  public void bar() {
    for (int i = 0; i < n; i++) {
      print("bar");
    }
  }
}
兩個不同的線程將會共用一個 FooBar 實例。其中一個線程將會調用 foo() 方法,另一個線程將會調用 bar() 方法。

請設計修改程序,以確保 "foobar" 被輸出 n 次。

 

示例 1:

輸入: n = 1
輸出: "foobar"
解釋: 這里有兩個線程被異步啟動。其中一個調用 foo() 方法, 另一個調用 bar() 方法,"foobar" 將被輸出一次。
示例 2:

輸入: n = 2
輸出: "foobarfoobar"
解釋: "foobar" 將被輸出兩次。

實現方案1——傳統方式

package com.lau.multithread.printinturn;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;


/** 
	交替打印FooBar——方案1:傳統方式
	我們提供一個類:
	
	class FooBar {
	  public void foo() {
	    for (int i = 0; i < n; i++) {
	      print("foo");
	    }
	  }
	
	  public void bar() {
	    for (int i = 0; i < n; i++) {
	      print("bar");
	    }
	  }
	}
	兩個不同的線程將會共用一個 FooBar 實例。其中一個線程將會調用 foo() 方法,另一個線程將會調用 bar() 方法。
	
	請設計修改程序,以確保 "foobar" 被輸出 n 次。
	
	
	示例 1:
	
	輸入: n = 1
	輸出: "foobar"
	解釋: 這里有兩個線程被異步啟動。其中一個調用 foo() 方法, 另一個調用 bar() 方法,"foobar" 將被輸出一次。
	示例 2:
	
	輸入: n = 2
	輸出: "foobarfoobar"
	解釋: "foobar" 將被輸出兩次。

*/

class FooBar {
	private volatile int n;
	
	private volatile int flag = 0;
	
	public FooBar(int n) {
		this.n = n;
	}
	
	public void foo() {
	   for (int i = 0; i < this.n; i++) {
		 synchronized (this) {
			try {
				while(0 != this.flag) {
					this.wait();
				}
				
				print("foo");
				
				flag = 1;
			} 
			catch (Exception e) {
				e.printStackTrace();
			}
			finally {
				this.notify();
			}
		 }
	   }
	}

	public void bar() {
		for (int i = 0; i < this.n; i++) {
			 synchronized (this) {
				try {
					while(1 != this.flag) {
						this.wait();
					}
					
					print("bar");
					
					flag = 0;
				} 
				catch (Exception e) {
					e.printStackTrace();
				}
				finally {
					this.notify();
				}
			 }
		 }
	}

	private void print(String target) {
		System.out.print(target);
	}
}


public class PrintInTurnDemo {

	public static void main(String[] args) {
		ExecutorService threadPool = Executors.newFixedThreadPool(3);
		
		FooBar fooBar = new FooBar(5);
		
		threadPool.submit(() -> fooBar.foo());
		threadPool.submit(() -> fooBar.bar());
		
		threadPool.shutdown();
	}

}

實現方案2——鎖方式

package com.lau.multithread.printinturn;

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;


/** 
	交替打印FooBar——方案2:鎖方式
	我們提供一個類:
	
	class FooBar {
	  public void foo() {
	    for (int i = 0; i < n; i++) {
	      print("foo");
	    }
	  }
	
	  public void bar() {
	    for (int i = 0; i < n; i++) {
	      print("bar");
	    }
	  }
	}
	兩個不同的線程將會共用一個 FooBar 實例。其中一個線程將會調用 foo() 方法,另一個線程將會調用 bar() 方法。
	
	請設計修改程序,以確保 "foobar" 被輸出 n 次。
	
	
	示例 1:
	
	輸入: n = 1
	輸出: "foobar"
	解釋: 這里有兩個線程被異步啟動。其中一個調用 foo() 方法, 另一個調用 bar() 方法,"foobar" 將被輸出一次。
	示例 2:
	
	輸入: n = 2
	輸出: "foobarfoobar"
	解釋: "foobar" 將被輸出兩次。

*/

class FooBar2 {
	private final Lock lock = new ReentrantLock();
	
	private final Condition fooCondition = lock.newCondition();
	private final Condition barCondition = lock.newCondition();
	
	private volatile int n;
	
	private volatile int flag = 0;
	
	public FooBar2(int n) {
		this.n = n;
	}
	
	public void foo() {
	   for (int i = 0; i < this.n; i++) {
			try {
				lock.lock();
				
				while(0 != this.flag) {
					fooCondition.await();
				}
				
				print("foo");
				
				flag = 1;
			} 
			catch (Exception e) {
				e.printStackTrace();
			}
			finally {
				barCondition.signal();
				
				lock.unlock();
			}
		 }
	}

	public void bar() {
		for (int i = 0; i < this.n; i++) {
			try {
				lock.lock();
				
				while(1 != this.flag) {
					barCondition.await();
				}
				
				print("bar");
				
				flag = 0;
			} 
			catch (Exception e) {
				e.printStackTrace();
			}
			finally {
				fooCondition.signal();
				
				lock.unlock();
			}
		 }
	}

	private void print(String target) {
		System.out.print(target);
	}
}


public class PrintInTurnDemo2 {

	public static void main(String[] args) {
		ExecutorService threadPool = Executors.newFixedThreadPool(2);
		
		FooBar2 fooBar = new FooBar2(3);
		
		threadPool.submit(() -> fooBar.foo());
		threadPool.submit(() -> fooBar.bar());
		
		threadPool.shutdown();
	}

}

實現方案3——信號量

package com.lau.multithread.printinturn;

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;


/** 
	交替打印FooBar——方案3:信號量方式
	我們提供一個類:
	
	class FooBar {
	  public void foo() {
	    for (int i = 0; i < n; i++) {
	      print("foo");
	    }
	  }
	
	  public void bar() {
	    for (int i = 0; i < n; i++) {
	      print("bar");
	    }
	  }
	}
	兩個不同的線程將會共用一個 FooBar 實例。其中一個線程將會調用 foo() 方法,另一個線程將會調用 bar() 方法。
	
	請設計修改程序,以確保 "foobar" 被輸出 n 次。
	
	
	示例 1:
	
	輸入: n = 1
	輸出: "foobar"
	解釋: 這里有兩個線程被異步啟動。其中一個調用 foo() 方法, 另一個調用 bar() 方法,"foobar" 將被輸出一次。
	示例 2:
	
	輸入: n = 2
	輸出: "foobarfoobar"
	解釋: "foobar" 將被輸出兩次。

*/

class FooBar3 {
	private final Semaphore fooSp = new Semaphore(1);
	private final Semaphore barSp = new Semaphore(0);
	
	private volatile int n;
	
	public FooBar3(int n) {
		this.n = n;
	}
	
	public void foo() {
	   for (int i = 0; i < this.n; i++) {
			try {
				fooSp.acquire();
				
				print("foo");
			} 
			catch (Exception e) {
				e.printStackTrace();
			}
			finally {
				barSp.release();
			}
		}
	}

	public void bar() {
		for (int i = 0; i < this.n; i++) {
			try {
				barSp.acquire();
				
				print("bar");
			} 
			catch (Exception e) {
				e.printStackTrace();
			}
			finally {
				fooSp.release();
			}
		}
	}

	private void print(String target) {
		System.out.print(target);
	}
}


public class PrintInTurnDemo3 {

	public static void main(String[] args) {
		ExecutorService threadPool = Executors.newFixedThreadPool(2);
		
		FooBar3 fooBar = new FooBar3(5);
		
		threadPool.submit(() -> fooBar.foo());
		threadPool.submit(() -> fooBar.bar());
		
		threadPool.shutdown();
	}

}

輸出:

foobarfoobarfoobarfoobarfoobar

關于leetcode中怎么利用多線程交替打印FooBar就分享到這里了,希望以上內容可以對大家有一定的幫助,可以學到更多知識。如果覺得文章不錯,可以把它分享出去讓更多的人看到。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

博客| 明星| 五华县| 淳化县| 贺兰县| 铁岭市| 五峰| 江西省| 扎兰屯市| 牟定县| 广德县| 石景山区| 资中县| 介休市| 麻栗坡县| 偃师市| 安多县| 台中市| 偏关县| 白山市| 永和县| 务川| 库尔勒市| 财经| 万山特区| 洞口县| 祁阳县| 吴江市| 宣化县| 大化| 筠连县| 茌平县| 阿尔山市| 罗平县| 敦化市| 垣曲县| 宕昌县| 凌源市| 沅江市| 阿瓦提县| 通州市|