日出星辰

          線程學習筆記【3】---互斥技術

          第一個示例更多的是運用了內部類的特性:

          內部類重要特點:可以訪問外部的成員變量,所以內部類不能在靜態方法中實例化

          因為靜態方法運行時不需要創建實例對象,而內部類想要訪問成員變量,意味著外部類肯定要創建實例對象,二者相互矛盾。

          所以下面就會報錯

          public class Synchronized01 {
          
          	public static void main(String args[]) {
          )
          		// final Outputer outputer=new Outputer(); //這樣做就沒有成員變量可以訪問
          		// new Thread(new Runnable(){
          		//
          		// public void run() {
          		// while(true){
          		// try {
          		// Thread.sleep(10);
          		// } catch (InterruptedException e) {
          		// e.printStackTrace();
          		// }
          		// outputer.outputer("zhangsan");
          		// }
          		// }}).start();
          	}
          class Outputer {
          		void outputer(String name) {
          			int len = name.length();
          			for (int i = 0; i < len; i++) {
          				System.out.print(name.charAt(i));
          			}
          			System.out.println();
          		}
          	}
          }
          

          但如果改成這樣就沒有問題

          public class Synchronized01 {
          
          	public static void main(String args[]) {	
                       new Synchronized01().init();
          	}
                   // 此方法被調用時一定創建了外部類對象
                   private void init() {
                                  // 運行時找外部類對象,找調用init方法的對象
          		final Outputer outputer = new Outputer(); 	
                                    	new Thread(new Runnable() {
                   			public void run() {
          				while (true) {
          					try {
          						Thread.sleep(10);
          					} catch (InterruptedException e) {
          						e.printStackTrace();
          					}
          					outputer.outputer("zhangsan");
          				}
          			}
          		}).start();
          		new Thread(new Runnable() {
          
          			public void run() {
          				while (true) {
          					try {
          						Thread.sleep(10);
          					} catch (InterruptedException e) {
          						e.printStackTrace();
          					}
          					outputer.outputer("lisi");
          				}
          			}
          		}).start();
          	}
          
          	class Outputer {
          		void outputer(String name) {
          			int len = name.length();
          			for (int i = 0; i < len; i++) {
          				System.out.print(name.charAt(i));
          			}
          			System.out.println();
          		}
          	}
          }

          運行結果

                  lisi zhangsan lisi zhangsan lisi zhangsan lisi zhangsan lisi zhangsan
                  lisi zhangsan lisi zhangsan lisi zhanlgissain
                  zlhiasnig san lzihsain gsan zlhiasnig san zlhiasnig san zlhiasnig san
                  zlhiasnigsan zlhiasnig san lzihsain gsan lisi zhangsan lisi

          解決方法

          修改Ouputer

          class Outputer {
          		public void outputer(String name) {
          			int len = name.length();
          			synchronized (this) {// 兩個線程用的是同一個outputer對象
          				for (int i = 0; i < len; i++) {
          					System.out.print(name.charAt(i));
          				}
          				System.out.println();
          			}
          		}
          
          		// synchronized要在void之前
          		// 一個方法只能有一個synchronized,不然可能會造成死鎖
          		public synchronized void outputer2(String name) {
          			int len = name.length();
          			for (int i = 0; i < len; i++) {
          				System.out.print(name.charAt(i));
          			}
          			System.out.println();
          		}
          
          	}
          	// class Outputer {
          	// String xxx = "";
          	//
          	// public void outputer(String name) {
          	// int len = name.length();
                       // xxx必須是同一個對象,如果是name就仍然會出錯 name是兩個對象
          	// synchronized (xxx) { 	
                       // for (int i = 0; i < len; i++) {
          	// System.out.print(name.charAt(i));
          	// }
          	// System.out.println();
          	// }
          	// }
          	//
          	// }

          但如果每個run()中這樣寫new Outputer()然后調用outputer(name)仍然會出錯,因為每次new都是產生一個新的對象,而synchronized關鍵是針對同一個對象。

          public class Synchronized02 {
          
          	public static void main(String[] args) {
          		new Synchronized02().init();
          	}
          
          	private void init() {
          		final Outputer outputer = new Outputer();
          		new Thread(new Runnable() {
          
          			public void run() { // 要執行的操作
          				while (true) { // 循環操作
          					try {
          						Thread.sleep(10);
          					} catch (InterruptedException e) {
          						e.printStackTrace();
          					}
          					outputer.outputer("zhangsan");
          				}
          			}
          		}).start();
          		new Thread(new Runnable() {
          
          			public void run() {
          				while (true) {
          					try {
          						Thread.sleep(10);
          					} catch (InterruptedException e) {
          						e.printStackTrace();
          					}
          					outputer.outputer("lisi");
                                                              //這樣仍然會出問題 ----不是同一個對象。
          				// new Outputer().outputer("lisi"); 				}
          			}
          		}).start();
          
          	}
          
          	class Outputer {
          		public void outputer(String name) {
          			int len = name.length();
          			synchronized (this) {// 兩個線程用的是同一個outputer對象
          				for (int i = 0; i < len; i++) {
          					System.out.print(name.charAt(i));
          				}
          				System.out.println();
          			}
          		}
          
          		// synchronized要在void之前
          		// 一個方法只能有一個synchronized,不然可能會造成死鎖
          		public synchronized void outputer2(String name) {
          			int len = name.length();
          			for (int i = 0; i < len; i++) {
          				System.out.print(name.charAt(i));
          			}
          			System.out.println();
          		}
          
          	}
          	// class Outputer {
          	// String xxx = "";
          	//
          	// public void outputer(String name) {
          	// int len = name.length();
                  // xxx必須是同一個對象,如果是name就仍然會出錯 name是兩個對象
          	// synchronized (xxx) {	
                      // for (int i = 0; i < len; i++) {
          	// System.out.print(name.charAt(i));
          	// }
          	// System.out.println();
          	// }
          	// }
          	//
          	// }
          
          }
          一個內部類前面加上static就變成了外部類
          靜態方法只能在外部類中聲明
          靜態方法只和字節碼對象有關
          public class Synchronized03 {
          
          	public static void main(String[] args) {
          		new Synchronized03().init();
          	}
          
          	private void init() {
          		final Outputer outputer = new Outputer();
          		new Thread(new Runnable() {
          
          			public void run() { // 要執行的操作
          				while (true) { // 循環操作
          					try {
          						Thread.sleep(10);
          					} catch (InterruptedException e) {
          						e.printStackTrace();
          					}
          					outputer.outputer("zhangsan");
          				}
          			}
          		}).start();
          		new Thread(new Runnable() {
          
          			public void run() {
          				while (true) {
          					try {
          						Thread.sleep(10);
          					} catch (InterruptedException e) {
          						e.printStackTrace();
          					}
          					outputer.outputer2("lisi");
          				}
          			}
          		}).start();
          
          	}
          
          	static class Outputer { // 加上static 相當于是個外部類
          		public void outputer(String name) {
          			int len = name.length();
                      // 靜態方法不創建類的實例對象,創建字節碼對象,靜態方法運行時只和字節碼對象關聯
          		synchronized (Outputer.class) {
          				for (int i = 0; i < len; i++) {
          					System.out.print(name.charAt(i));
          				}
          				System.out.println();
          			}
          		}
          
          		// synchronized要在void之前
                                   // 靜態方法只能在外部類中聲明
          		public static synchronized void outputer2(String name) { 	
          		int len = name.length();
          			for (int i = 0; i < len; i++) {
          				System.out.print(name.charAt(i));
          			}
          			System.out.println();
          		}
          
          	}
          
          }

          posted on 2011-08-29 15:10 日出星辰 閱讀(73) 評論(0)  編輯  收藏


          只有注冊用戶登錄后才能發表評論。


          網站導航:
           
          主站蜘蛛池模板: 苏尼特左旗| 图们市| 霍林郭勒市| 久治县| 清徐县| 藁城市| 阿拉善左旗| 子洲县| 宁化县| 天津市| 晋江市| 南昌市| 广汉市| 新龙县| 永州市| 永善县| 吕梁市| 龙游县| 淮阳县| 庆元县| 云霄县| 宣城市| 闻喜县| 武乡县| 万州区| 资兴市| 沙河市| 北流市| 焦作市| 昌黎县| 兴宁市| 阿拉善盟| 沁水县| 信丰县| 华坪县| 玛沁县| 女性| 安徽省| 舞钢市| 蒙自县| 盐边县|