黑马程序员--线程【下】
生活随笔
收集整理的這篇文章主要介紹了
黑马程序员--线程【下】
小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.
-------------------?android培訓(xùn)、java培訓(xùn)、期待與您交流!------------------
?
?
?/* 線程間通訊: 其實(shí)就是多個(gè)線程在操作同一個(gè)資源, 但是操作的動(dòng)作不同。 優(yōu)化! */ class Res { private String name; private String sex; private boolean flag = false;//開(kāi)始時(shí),沒(méi)數(shù)據(jù),就false public synchronized void set(String name,String sex) { if(flag) try{this.wait();}catch(Exception e){}//等待 this.name = name; //不同步,中間可能會(huì)出現(xiàn)問(wèn)題 this.sex = sex; flag = true; this.notify();//喚醒 } public synchronized void out() { if(!flag) try{this.wait();}catch(Exception e){} System.out.println(name+"........"+sex); flag = false; this.notify(); } } class Input implements Runnable { private Res r ; Input(Res r) { this.r = r; } public void run() { int x = 0; while(true) { if(x==0) r.set("mike","man"); else r.set("麗麗","女女女女女"); x = (x+1)%2; } } } class Output implements Runnable { private Res r ; Output(Res r) { this.r = r; } public void run() { while(true) { r.out(); } } } class ?InputOutputDemo2 { public static void main(String[] args)? { Res r = new Res(); //簡(jiǎn)化:6句2句 new Thread(new Input(r)).start(); new Thread(new Output(r)).start(); /* Input in = new Input(r); Output out = new Output(r); Thread t1 = new Thread(in); Thread t2 = new Thread(out); t1.start(); t2.start(); */ } } ------------------------------------------------------------------------------------------------------------???
class ProducerConsumerDemo? { public static void main(String[] args)? { Resource r = new Resource(); Producer pro = new Producer(r); Consumer con = new Consumer(r); //兩個(gè)線程生產(chǎn),兩個(gè)線程消費(fèi) Thread t1 = new Thread(pro); Thread t2 = new Thread(pro); Thread t3 = new Thread(con); Thread t4 = new Thread(con); t1.start(); t2.start(); t3.start(); t4.start(); } } /* 對(duì)于多個(gè)生產(chǎn)者和消費(fèi)者。 為什么要定義while判斷標(biāo)記。 原因:讓被喚醒的線程再一次判斷標(biāo)記。---否則會(huì)出現(xiàn)問(wèn)題:生產(chǎn)一個(gè)消費(fèi)兩次,或者生產(chǎn)兩次消費(fèi)一次 為什么定義notifyAll, 因?yàn)樾枰獑拘褜?duì)方線程。 因?yàn)橹挥胣otify,容易出現(xiàn)只喚醒本方線程的情況。導(dǎo)致程序中的所有線程都等待【死鎖】。 */ class Resource { private String name; private int count = 1; private boolean flag = false; // ?t1 ? ?t2 public synchronized void set(String name) { while(flag)//每次醒來(lái)都必須判斷,否則(if)會(huì)出現(xiàn)問(wèn)題:生產(chǎn)兩個(gè),消費(fèi)一次 try{this.wait();}catch(Exception e){}//t1(放棄資格) ?t2(獲取資格),【用if之判斷一次】醒來(lái)之后,不用判斷標(biāo)記,直接向下執(zhí)行,導(dǎo)致生產(chǎn)兩個(gè)//開(kāi)發(fā)要寫多行,不能寫在一行 this.name = name+"--"+count++; System.out.println(Thread.currentThread().getName()+"...生產(chǎn)者.."+this.name); flag = true; //this.notify();//出現(xiàn)死鎖 this.notifyAll(); } // ?t3 ? t4 ? public synchronized void out() { while(!flag)//每次醒來(lái)都必須判斷,否則(if)會(huì)出現(xiàn)問(wèn)題:生產(chǎn)一個(gè)消費(fèi)兩次; try{wait();}catch(Exception e){}//t3(放棄資格) t4(放棄資格) System.out.println(Thread.currentThread().getName()+"...消費(fèi)者........."+this.name); flag = false; //this.notify();//出現(xiàn)死鎖 this.notifyAll(); } } class Producer implements Runnable { private Resource res; Producer(Resource res) { this.res = res; } public void run() { while(true) { res.set("+商品+"); } } } class Consumer implements Runnable { private Resource res; Consumer(Resource res) { this.res = res; } public void run() { while(true) { res.out(); } } }
------------------------------------------------------------------------------------------------------------????
?
import java.util.concurrent.locks.*; class ProducerConsumerDemo2? { public static void main(String[] args)? { Resource r = new Resource(); Producer pro = new Producer(r); Consumer con = new Consumer(r); Thread t1 = new Thread(pro); Thread t2 = new Thread(pro); Thread t3 = new Thread(con); Thread t4 = new Thread(con); t1.start(); t2.start(); t3.start(); t4.start(); } } /* JDK1.5 中提供了多線程升級(jí)解決方案。 將同步Synchronized替換成顯式的Lock操作。 將Object中的wait,notify notifyAll,替換了Condition對(duì)象。 該對(duì)象可以Lock鎖 進(jìn)行獲取。 該示例中,實(shí)現(xiàn)了本方只喚醒對(duì)方操作。 Lock:替代了Synchronized lock? unlock newCondition() Condition:替代了Object wait notify notifyAll await(); signal(); signalAll(); */ class Resource { private String name; private int count = 1; private boolean flag = false; // ?t1 ? ?t2 private Lock lock = new ReentrantLock(); //一個(gè)鎖可以有多個(gè)condition對(duì)象 private Condition condition_pro = lock.newCondition();//生產(chǎn)者對(duì)象 private Condition condition_con = lock.newCondition();//消費(fèi)者對(duì)象 public ?void set(String name)throws InterruptedException { lock.lock(); try { while(flag) condition_pro.await();//t1,t2//生產(chǎn)者等待 this.name = name+"--"+count++; System.out.println(Thread.currentThread().getName()+"...生產(chǎn)者.."+this.name); flag = true; condition_con.signal();//喚醒消費(fèi)者 } finally { lock.unlock();//釋放鎖的動(dòng)作一定要執(zhí)行。 } } // ?t3 ? t4 ? public ?void out()throws InterruptedException { lock.lock(); try { while(!flag) condition_con.await();//消費(fèi)者等待t3,t4 System.out.println(Thread.currentThread().getName()+"...消費(fèi)者........."+this.name); flag = false; condition_pro.signal();//喚醒生產(chǎn)者 } finally { lock.unlock(); } } } class Producer implements Runnable { private Resource res; Producer(Resource res) { this.res = res; } public void run() { while(true) { try { res.set("+商品+"); } catch (InterruptedException e) { } } } } class Consumer implements Runnable { private Resource res; Consumer(Resource res) { this.res = res; } public void run() { while(true) { try { res.out(); } catch (InterruptedException e) { } } } }------------------------------------------------------------------------------------------------------------?
/* stop方法已經(jīng)過(guò)時(shí)。 如何停止線程? 只有一種,run方法結(jié)束。 開(kāi)啟多線程運(yùn)行,運(yùn)行代碼通常是循環(huán)結(jié)構(gòu)。 只要控制住循環(huán),就可以讓run方法結(jié)束,也就是線程結(jié)束。 特殊情況: 當(dāng)線程處于了凍結(jié)狀態(tài)。 就不會(huì)讀取到標(biāo)記。那么線程就不會(huì)結(jié)束。 當(dāng)沒(méi)有指定的方式讓凍結(jié)的線程恢復(fù)到運(yùn)行狀態(tài)時(shí),這時(shí)需要對(duì)凍結(jié)進(jìn)行清除。 強(qiáng)制讓線程恢復(fù)到運(yùn)行狀態(tài)中來(lái)。這樣就可以操作標(biāo)記讓線程結(jié)束。 Thread類提供該方法 interrupt();//sleep,wait,join都能被他中斷 */ class StopThread implements Runnable { private boolean flag =true; public ?void run() { while(flag) { /* try { wait(); } catch(InterruptedException e) { System.out.println(Thread.currentThread().getName()+"....run"); } */ System.out.println(Thread.currentThread().getName()+"....run"); } } public void changeFlag()//改變標(biāo)記方法,控制停止! { flag = false; } } class ?StopThreadDemo { public static void main(String[] args)? { StopThread st = new StopThread(); Thread t1 = new Thread(st); Thread t2 = new Thread(st); t1.setDaemon(true);//在啟動(dòng)線程前調(diào)用守護(hù)線程【后臺(tái)線程】。//前臺(tái)線程結(jié)束,后臺(tái)線程自動(dòng)結(jié)束 t2.setDaemon(true); t1.start(); t2.start(); int num = 0; while(true) { if(num++ == 60) { //st.changeFlag(); //t1.interrupt();//不該喚醒,喚醒了,會(huì)出現(xiàn)異常! //t2.interrupt(); break; } System.out.println(Thread.currentThread().getName()+"......."+num); } System.out.println("over"); } }
------------------------------------------------------------------------------------------------------------??
/* join: 當(dāng)A線程執(zhí)行到了B線程的.join()方法時(shí),A就會(huì)等待。等B線程都執(zhí)行完,A才會(huì)執(zhí)行。 join可以用來(lái)臨時(shí)加入線程執(zhí)行。 */ class Demo implements Runnable { public void run() { for(int x=0; x<70; x++) { //System.out.println(Thread.currentThread().getName()+"....."+x); System.out.println(Thread.currentThread().toString()+"....."+x); Thread.yield();//暫停現(xiàn)在正在執(zhí)行的線程,執(zhí)行其他線程,延緩線程的運(yùn)行 } } } class ?JoinDemo { public static void main(String[] args) throws Exception { Demo d = new Demo(); Thread t1 = new Thread(d); Thread t2 = new Thread(d); t1.start(); //t1.join();//搶奪cpu執(zhí)行權(quán),主線程凍結(jié)【不會(huì)跟t1搶執(zhí)行權(quán)】,t1執(zhí)行完,主線程恢復(fù)執(zhí)行權(quán) //t1.setPriority(Thread.MAX_PRIORITY);//設(shè)置最高優(yōu)先級(jí) t2.start(); //t1.join();//搶奪cpu執(zhí)行權(quán),主線程凍結(jié)【不會(huì)跟t1搶執(zhí)行權(quán)】,---t1和t2交替執(zhí)行-----t1執(zhí)行完,主線程恢復(fù)執(zhí)行權(quán),不管t2是否執(zhí)行完 for(int x=0; x<80; x++) { //System.out.println("main....."+x); } System.out.println("over"); } }
------------------------------------------------------------------------------------------------------------?
//開(kāi)發(fā)的時(shí)候可以這么寫! class ThreadTest? { public static void main(String[] args)? { //線程1 new Thread()//匿名內(nèi)部類//Thread子類對(duì)象 { public void run() { for(int x=0; x<100; x++) { System.out.println(Thread.currentThread().getName()+"....."+x); } } }.start(); //線程2【主線程】 for(int x=0; x<100; x++) { System.out.println(Thread.currentThread().getName()+"....."+x); } //線程3 Runnable r ?= new Runnable() { public void run() { for(int x=0; x<100; x++) { System.out.println(Thread.currentThread().getName()+"....."+x); } } }; new Thread(r).start(); //new Test1().start();//用匿名內(nèi)部類代替外部類 } } /* class Test1 extends Thread { public void run() { for(int x=0; x<100; x++) { System.out.println(Thread.currentThread().getName()+"....."+x); } } } */
轉(zhuǎn)載于:https://www.cnblogs.com/Stone-sw/archive/2013/03/15/2962331.html
總結(jié)
以上是生活随笔為你收集整理的黑马程序员--线程【下】的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: [转载] 中华典故故事(孙刚)——24
- 下一篇: 2440-系统时钟