亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 編程 > Java > 正文

Java多線程(二)

2019-11-06 06:59:22
字體:
來源:轉載
供稿:網友

一、使用同步解決買票問題

解決資源共享的同步操作問題,可以使用同步代碼塊和同步方法兩種方式。

第一種:使用同步代碼塊必須指定一個需要同步的對象,通常將當前對象(this)設置成同步對象。

class SaleTask implements Runnable{	PRivate int ticket = 5;//剩余票數	public void run() {		if(ticket>0){			System.out.println("線程"+Thread.currentThread().getName()+"需要賣票");			synchronized (this) {				if(ticket>0){					try {						Thread.sleep(2000);					} catch (InterruptedException e) {						e.printStackTrace();					}					System.out.println("線程"+Thread.currentThread().getName()+							"賣了一張票,剩余票數"+(--ticket)+"張");				}else{					System.out.println("線程"+Thread.currentThread().getName()+"需要賣票,已無票");				}			}		}else{			System.out.println("線程"+Thread.currentThread().getName()+"需要賣票,已無票");		}	}}public class Main {	public static void main(String[] args){		SaleTask sale = new SaleTask();		for(int i=0;i<8;i++){	//有8個線程需要賣票			Thread t1 = new Thread(sale,"thread"+(i+1));			t1.start();		}	}}

運行結果:

線程thread1需要賣票線程thread3需要賣票線程thread2需要賣票線程thread6需要賣票線程thread7需要賣票線程thread4需要賣票線程thread8需要賣票線程thread5需要賣票線程thread1賣了一張票,剩余票數4張線程thread5賣了一張票,剩余票數3張線程thread8賣了一張票,剩余票數2張線程thread4賣了一張票,剩余票數1張線程thread7賣了一張票,剩余票數0張線程thread6需要賣票,已無票線程thread2需要賣票,已無票線程thread3需要賣票,已無票第二種:同步方法

	public synchronized void run() {		if(ticket>0){			System.out.println("線程"+Thread.currentThread().getName()+					"需要賣票");			if(ticket>0){				try {					Thread.sleep(2000);				} catch (InterruptedException e) {					e.printStackTrace();				}				System.out.println("線程"+Thread.currentThread().getName()+						"賣了一張票,剩余票數"+(--ticket)+"張");			}else{				System.out.println("線程"+Thread.currentThread().getName()+						"需要賣票,已無票");			}		}else{			System.out.println("線程"+Thread.currentThread().getName()+					"需要賣票,已無票");		}	}

運行結果:

線程thread1需要賣票線程thread1賣了一張票,剩余票數4張線程thread7需要賣票線程thread7賣了一張票,剩余票數3張線程thread3需要賣票線程thread3賣了一張票,剩余票數2張線程thread8需要賣票線程thread8賣了一張票,剩余票數1張線程thread4需要賣票線程thread4賣了一張票,剩余票數0張線程thread6需要賣票,已無票線程thread5需要賣票,已無票線程thread2需要賣票,已無票

二、死鎖

多個線程共享同一資源時需要進行同步,以保證資源操作的完整性,但是過多的同步就有可能產生死鎖。

class ThreadTask implements Runnable{	private static String resourceA = "Resource A";	private static String resourceB = "Resource B";	public boolean flag;//標記獲取資源的順序,true表示先獲取A,再獲取B;false則相反		public void run() {		if(flag){			synchronized(resourceA){				System.out.println("線程"+Thread.currentThread().getName()+"獲取了資源A");				try{					Thread.sleep(500);				}catch(InterruptedException e){					e.printStackTrace();				}				synchronized(resourceB){					System.out.println("線程"+Thread.currentThread().getName()+"獲取了資源B");				}			}		}		else{			synchronized(resourceB){				System.out.println("線程"+Thread.currentThread().getName()+"獲取了資源B");				try{					Thread.sleep(500);				}catch(InterruptedException e){					e.printStackTrace();				}				synchronized(resourceA){					System.out.println("線程"+Thread.currentThread().getName()+"獲取了資源A");				}			}		}	}}public class Main {	public static void main(String[] args){		ThreadTask task1 = new ThreadTask();		ThreadTask task2 = new ThreadTask();		task1.flag = true;		task2.flag = false;		Thread t1 = new Thread(task1,"thread-1");		Thread t2 = new Thread(task2,"thread-2");		t1.start();		t2.start();	}}

運行結果:

線程thread-1獲取了資源A線程thread-2獲取了資源B 兩個線程都在等待對方釋放手中的資源,這樣就產生了死鎖。

三、線程操作案例——生產者與消費者

線程操作中一個典型的案例——生產者與消費者問題,生產者不斷生產,消費者不斷消費生產者生產的產品。

從中可以看出,生產者產生資源后將資源放到一個區域中,消費者從這個區域中取出產品,由于線程運行的不確定性,可能會產生下面兩種問題:

1)生產者剛向數據存儲空間中添加了信息的名稱,還沒有添加信息的內容,程序就切換到了消費者線程,這樣消費者線程讀取到的是更新后的信息的名稱和上一次信息的內容。

2)生產者連續更新了多次信息,消費者才開始讀取,或者,消費者連續多次讀取信息,生產者卻還沒來及更新。

1.程序的基本實現

無論是生產者還是消費者,操作的都是信息(資源),所以需要定義一個信息類。

//信息類(資源)class Info {	private String name = "李興華";						//資源name	private String content = "java講師";					//資源content		public void setName(String name){		this.name = name;	}	public String getName(){		return name;	}	public void setContent(String content){		this.content = content;	}	public String getContent(){		return content;	}}

生產者和消費者相當于兩個線程,操作同一個空間,分別實現Runnable接口

//生產者線程class Producer implements Runnable{	private Info info = null;						//資源的引用		public Producer(Info info){		this.info = info;	}	public void run() {		boolean flag = false;		for(int i=0;i<50;i++){						//循環50次讓生產者生產具體的內容			if(flag){				this.info.setName("李興華");				try{					Thread.sleep(90);				}catch(InterruptedException e){					e.printStackTrace();				}				this.info.setContent("Java講師");				flag = false;			}else{				this.info.setName("mldn");				try{					Thread.sleep(90);				}catch(InterruptedException e){					e.printStackTrace();				}				this.info.setContent("www.mldnjava.cn");				flag = true;			}		}	}}
//消費者線程class Consumer implements Runnable{	private Info info = null;						//資源的引用		public Consumer(Info info){		this.info = info;	}	public void run() {		for(int i=0;i<50;i++){			try{				Thread.sleep(110);			}catch(InterruptedException e){				e.printStackTrace();			}			System.out.println(this.info.getName()+"--->"+this.info.getContent());		}	}}

主方法:

public class Main {	public static void main(String[] args){		Info i = new Info();		Producer p = new Producer(i);		Consumer c = new Consumer(i);		Thread pt = new Thread(p,"thread-1");		Thread ct = new Thread(c,"thread-2");		pt.start();		ct.start();	}}

運行結果:

李興華--->www.mldnjava.cnmldn--->Java講師李興華--->www.mldnjava.cnmldn--->Java講師mldn--->Java講師李興華--->www.mldnjava.cnmldn--->Java講師李興華--->www.mldnjava.cn李興華--->www.mldnjava.cnmldn--->Java講師......

2.解決問題1——加入同步

將設置信息的方法和獲取信息的方法都設為同步方法,使得無論是設置信息還是讀取信息,都需要先獲取信息對象,在一段時間內,只有一個線程可以對資源進行操作。

//信息類(資源)class Info {	private String name = "李興華";						//資源name	private String content = "Java講師";					//資源content	public synchronized void set(String name,String content){		setName(name);		try{			Thread.sleep(90);					//加入延遲		}catch(InterruptedException e){			e.printStackTrace();		}		setContent(content);	}	public synchronized void get(){		try{			Thread.sleep(100);					//加入延遲		}catch(InterruptedException e){			e.printStackTrace();		}		System.out.println(getName()+"--->"+getContent());	}	public void setName(String name){		this.name = name;	}	public String getName(){		return name;	}	public void setContent(String content){		this.content = content;	}	public String getContent(){		return content;	}}

生產者:

//生產者線程class Producer implements Runnable{	private Info info = null;						//資源的引用		public Producer(Info info){		this.info = info;	}	public void run() {		boolean flag = false;		for(int i=0;i<50;i++){			if(flag){				this.info.set("李興華", "Java講師");				flag = false;			}else{				this.info.set("mldn", "www.mldnjava.cn");				flag = true;			}		}	}}

消費者:

//消費者線程class Consumer implements Runnable{	private Info info = null;						//資源的引用		public Consumer(Info info){		this.info = info;	}	public void run() {		for(int i=0;i<50;i++){			this.info.get();		}	}}

mldn--->www.mldnjava.cn李興華--->Java講師mldn--->www.mldnjava.cnmldn--->www.mldnjava.cn李興華--->Java講師李興華--->Java講師李興華--->Java講師mldn--->www.mldnjava.cn李興華--->Java講師李興華--->Java講師......

從運行結果可以看出,信息錯亂的問題解決了,但是仍然存在信息重復讀取的問題,既然有重復讀取,就有重復設置,對于這樣的問題需要用到Object類。

 

3.Object類對線程的支持

1.Object類有以下幾種方法是對線程支持的:

 

從表中可知,可以將線程設為等待狀態,也可以喚醒線程。喚醒線程的方法有兩個,所有等待的線程一般會按照順序排列,如果用notify()方法喚醒,則會喚醒第一個線程,若用notifyAll()方法喚醒,則會喚醒所有的等待線程,哪一個線程的優先級高,哪一個線程就有可能先執行。

 

2.解決問題2——加入等待與喚醒

如果想讓生產者不重復生產,消費者不重復讀取,可以增加一個標志位,標志位為boolean型,

若為true,表示生產者可以生產,但消費者不可以讀取,如果是消費者線程則需要等待;

若為false,表示消費者可以讀取,但生產者不可以生產,如果是生產者線程則需要等待。

 

要完成以上功能,直接修改Info類即可,在Info類中增加一個標志位,通過判斷標志位完成等待與喚醒操作。

//信息類(資源)class Info {         privateString name = "李興華";                                                //資源name         privateString content = "Java講師";                                           //資源content         privateboolean flag = false;                                                  //true,表示可以生產,不能消費                                                                                       //false表示可以消費,不能生產         //生產資源         publicsynchronized void set(String name,String content){                   if(!flag){                                                          //為false時,生產者線程等待                            try{                                     super.wait();                                     //wait()方法會讓線程釋放手中的鎖                            }catch (InterruptedException e) {                                     e.printStackTrace();                            }                   }                   setName(name);                   try{                            Thread.sleep(90);                                          //加入延遲                   }catch(InterruptedExceptione){                            e.printStackTrace();                   }                   setContent(content);                   this.flag= false;                   super.notify();                                                     //喚醒等待的線程         }         //消費資源         publicsynchronized void get(){                   if(flag){                            try{                                     super.wait();                            }catch (InterruptedException e) {                                     e.printStackTrace();                            }                   }                   try{                            Thread.sleep(100);                                          //加入延遲                   }catch(InterruptedExceptione){                            e.printStackTrace();                   }                   System.out.println(getName()+"--->"+getContent());                   this.flag= true;                   super.notify();                                                      //喚醒等待的線程         }                 publicvoid setName(String name){                   this.name= name;         }         publicString getName(){                   returnname;         }         publicvoid setContent(String content){                   this.content= content;         }         publicString getContent(){                   returncontent;         }}

運行結果:

李興華--->Java講師mldn--->www.mldnjava.cn李興華--->Java講師mldn--->www.mldnjava.cn李興華--->Java講師mldn--->www.mldnjava.cn李興華--->Java講師mldn--->www.mldnjava.cn李興華--->Java講師mldn--->www.mldnjava.cn......

從運行結果可以發現,生產者每生產一個資源就要等待消費者取走,消費者每取走一個就要等待生產者生產,這樣就避免了重復生產和重復取走的問題。

 

四、線程的生命周期

 

其中3個方法:

suspend():暫時掛起線程

resume():回復掛起的線程

stop():停止線程

但這三種方法不推薦使用,因為使用這三種方法會產生死鎖的問題,在源代碼中這三個方法使用了@Deprecated


發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
九九九热精品免费视频观看网站| 亚洲天堂成人在线视频| 亚洲深夜福利在线| 亚洲欧洲在线视频| 欧美日韩亚洲国产一区| 亚洲乱码av中文一区二区| 一区二区欧美激情| 中文字幕亚洲天堂| 亚洲欧洲偷拍精品| 久久久久久国产精品三级玉女聊斋| 这里只有精品在线观看| 欧美美最猛性xxxxxx| 精品动漫一区二区| 日韩精品极品毛片系列视频| 国产欧美中文字幕| 久久精品青青大伊人av| 亚洲高清久久久久久| 57pao成人永久免费视频| 国产精品一区二区性色av| 欧美午夜视频一区二区| 国内精品久久久久伊人av| 亚州国产精品久久久| 高清在线视频日韩欧美| 日韩精品在线播放| 国产视频欧美视频| 精品久久久久久电影| 亚洲国产精品视频在线观看| 国内成人精品视频| 自拍偷拍亚洲区| 国产一区二区三区毛片| 欧美日韩加勒比精品一区| 久久精品色欧美aⅴ一区二区| 最新91在线视频| 欧美激情一二三| 亚洲国产精品成人av| 色综合色综合久久综合频道88| 国产精品jizz在线观看麻豆| 福利二区91精品bt7086| 欧美日韩成人在线观看| 日韩高清中文字幕| 高清欧美性猛交xxxx黑人猛交| 日韩精品一区二区视频| 欧美在线视频一二三| 亚洲国产古装精品网站| 欧美视频二区36p| 亚洲视频在线免费观看| 欧美第一黄网免费网站| 最近中文字幕mv在线一区二区三区四区| 久久久久久91香蕉国产| 国产日韩欧美夫妻视频在线观看| 高清日韩电视剧大全免费播放在线观看| 在线观看国产欧美| 欧美大人香蕉在线| 日韩av在线一区| 国产精品精品视频一区二区三区| 亚洲一区美女视频在线观看免费| 国产999精品久久久影片官网| 日韩在线观看免费全| 神马国产精品影院av| 精品中文字幕乱| 亚洲黄一区二区| 亚洲国产中文字幕在线观看| 国产精品91久久久久久| 国产成人精彩在线视频九色| 国产+成+人+亚洲欧洲| 亚洲精品在线91| 成人疯狂猛交xxx| 日韩中文字幕免费视频| 九九热99久久久国产盗摄| 菠萝蜜影院一区二区免费| 国产精品普通话| 国产欧美精品在线播放| 国产免费一区二区三区在线观看| 国产一区二区激情| 日韩有码在线电影| 欧美做受高潮电影o| 国产午夜精品一区二区三区| 欧美精品videosex性欧美| 国产精品欧美在线| 亚洲性生活视频| 91精品久久久久| 国产精品福利在线观看网址| 欧美成人激情在线| 疯狂做受xxxx欧美肥白少妇| 久久久伊人欧美| 91av中文字幕| 成人黄色av网| 亚洲高清福利视频| 亚洲欧美在线x视频| 97精品视频在线播放| 国产做受69高潮| 欧美裸体xxxx极品少妇软件| 欧美日韩一区免费| 国产91露脸中文字幕在线| 国产精品极品尤物在线观看| 欧美精品久久一区二区| 亚洲成人av资源网| 亚洲一区免费网站| 久久亚洲影音av资源网| 欧美日韩国产影院| 欧美三级欧美成人高清www| 欧美日韩国产精品一区二区三区四区| 国内偷自视频区视频综合| 欧美日韩国产成人高清视频| 国产欧美精品日韩| 91产国在线观看动作片喷水| 中文字幕精品影院| 中文字幕精品视频| 日韩中文字幕免费| 国产精品福利无圣光在线一区| 久久人人爽人人| 裸体女人亚洲精品一区| 欧美日韩国产精品一区二区三区四区| 国产成人精品电影久久久| 久操成人在线视频| 日韩免费不卡av| 91久久精品久久国产性色也91| 7777免费精品视频| 亚洲色无码播放| 国产99视频在线观看| 国产精品久久激情| 狠狠久久亚洲欧美专区| 国产成人免费91av在线| 国产性猛交xxxx免费看久久| 欧洲美女免费图片一区| 欧美自拍视频在线| 在线亚洲男人天堂| 久久久999国产精品| 成人欧美在线观看| 1769国产精品| 欧美巨乳在线观看| 国产精品高清网站| 欧美性少妇18aaaa视频| 97久久精品人搡人人玩| 欧美性xxxxxx| 亚洲国产精品va| 日韩av男人的天堂| 日韩中文字在线| 欧美三级免费观看| 国产亚洲一区精品| 日本久久久久久久久久久| 国产精品国产三级国产aⅴ浪潮| 亚洲精品自在久久| 亚洲va电影大全| 亚洲欧美中文字幕| 欧美日韩亚洲高清| 欧美电影第一页| 欧美日韩国产在线| 91香蕉嫩草影院入口| 96pao国产成视频永久免费| 欧美疯狂xxxx大交乱88av| 国产亚洲视频在线| 91欧美激情另类亚洲| 成人av资源在线播放| 大量国产精品视频| 国产99久久精品一区二区| 久久久久久久一区二区| 亚洲人在线视频| 欧美巨乳美女视频| 国产成人自拍视频在线观看| 日韩美女在线播放| 色综合久久88色综合天天看泰| 欧美乱大交xxxxx另类电影| 国产精品永久免费在线|