日出星辰

          My Links

          Blog Stats

          常用鏈接

          留言簿

          隨筆檔案

          搜索

          最新評論

          閱讀排行榜

          評論排行榜

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

          第一個示例更多的是運用了內(nèi)部類的特性:

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

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

          所以下面就會報錯

          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();
          	}
                   // 此方法被調(diào)用時一定創(chuàng)建了外部類對象
                   private void init() {
                                  // 運行時找外部類對象,找調(diào)用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()然后調(diào)用outputer(name)仍然會出錯,因為每次new都是產(chǎn)生一個新的對象,而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() { // 要執(zhí)行的操作
          				while (true) { // 循環(huán)操作
          					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();
          	// }
          	// }
          	//
          	// }
          
          }
          一個內(nèi)部類前面加上static就變成了外部類
          靜態(tài)方法只能在外部類中聲明
          靜態(tài)方法只和字節(jié)碼對象有關
          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() { // 要執(zhí)行的操作
          				while (true) { // 循環(huán)操作
          					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();
                      // 靜態(tài)方法不創(chuàng)建類的實例對象,創(chuàng)建字節(jié)碼對象,靜態(tài)方法運行時只和字節(jié)碼對象關聯(lián)
          		synchronized (Outputer.class) {
          				for (int i = 0; i < len; i++) {
          					System.out.print(name.charAt(i));
          				}
          				System.out.println();
          			}
          		}
          
          		// synchronized要在void之前
                                   // 靜態(tài)方法只能在外部類中聲明
          		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)  編輯  收藏


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


          網(wǎng)站導航:
           
          主站蜘蛛池模板: 庐江县| 平凉市| 和田市| 二手房| 普兰店市| 开阳县| 伊宁市| 武平县| 大英县| 仁布县| 英吉沙县| 乌兰县| 佛学| 澳门| 昭平县| 巍山| 阿克陶县| 清涧县| 息烽县| 永福县| 新余市| 徐汇区| 丹凤县| 确山县| 桦甸市| 壤塘县| 鹿邑县| 彭阳县| 利津县| 军事| 通化县| 凯里市| 汽车| 泰州市| 安陆市| 陇西县| 凤山市| 大厂| 苗栗县| 宁强县| 天柱县|