日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 人文社科 > 生活经验 >内容正文

生活经验

黑马程序员5 多线程

發布時間:2023/11/27 生活经验 28 豆豆
生活随笔 收集整理的這篇文章主要介紹了 黑马程序员5 多线程 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

------- android培訓、java培訓、期待與您交流! ----------

創建線程的第一種方式:繼承Thread類。
步驟:
1,定義類繼承Thread。
2,復寫Thread類中的run方法。
目的:將自定義代碼存儲在run方法。讓線程運行。

3,調用線程的start方法,
該方法兩個作用:啟動線程,調用run方法。

創建線程的第二種方式:實現Runable接口

步驟:
1,定義類實現Runnable接口
2,覆蓋Runnable接口中的run方法。
將線程要運行的代碼存放在該run方法中。

3,通過Thread類建立線程對象。
4,將Runnable接口的子類對象作為實際參數傳遞給Thread類的構造函數。
為什么要將Runnable接口的子類對象傳遞給Thread的構造函數。
因為,自定義的run方法所屬的對象是Runnable接口的子類對象。
所以要讓線程去指定指定對象的run方法。就必須明確該run方法所屬對象。

5,調用Thread類的start方法開啟線程并調用Runnable接口子類的run方法。

實現方式和繼承方式有什么區別呢?

實現方式好處:避免了單繼承的局限性。
在定義線程時,建立使用實現方式。

兩種方式區別:
繼承Thread:線程代碼存放Thread子類run方法中。
實現Runnable,線程代碼存在接口的子類的run方法。

范例:

public class Test1 {public static void main(String[] args) {for(int i=0;i<3;i++){new Thread(new Mess()).start();}}
}class Mess implements Runnable{private static int taskcount = 0;private final int id = taskcount ++;Mess(){System.out.println("new message"+id);}@Overridepublic void run() {System.out.println("r1:"+id);Thread.yield();  //對線程調度器的一種建議System.out.println("r2:"+id);Thread.yield();System.out.println("r3:"+id);Thread.yield();System.out.println("end"+id);}
}

=========================================================

Java對于多線程的安全問題提供了專業的解決方式。

就是同步代碼塊。

synchronized(對象)
{
需要被同步的代碼

}
對象如同鎖。持有鎖的線程可以在同步中執行。
沒有持有鎖的線程即使獲取cpu的執行權,也進不去,因為沒有獲取鎖。


同步規則(何時使用同步):如果正在寫一個變量,他可能接下來被另一個線程讀取,或者正在讀取一個上一次已經被另一個線程寫過的變量,必須使用同步,并且,讀寫線程都必須用相同的監視器鎖同步。


同步函數的鎖是this
靜態同步函數的鎖是Class對象。

?

public class Test1 {public static void main(String[] args) {for(int i=0;i<3;i++){new Thread(new Mess()).start();}}
}class Mess implements Runnable{private static int taskcount = 0;private final int id = taskcount ++;Mess(){System.out.println("new message"+id);}@Overridepublic void run() {System.out.println("r1:"+id);Thread.yield();  //對線程調度器的一種建議System.out.println("r2:"+id);Thread.yield();System.out.println("r3:"+id);Thread.yield();System.out.println("end"+id);}
}

=======================================================

等待/喚醒機制
涉及的方法:
1.wait():讓線程處于凍結狀態,被wait的線程會被存儲到線程池中。
2.notify():喚醒線程池中的一個線程(任意)。
3.notifyAll():喚醒線程池中的所有線程。

這些方法都必須定義在同步中,因為這些方法是用于操作線程狀態的方法,
必須要明確到底操作的是哪個鎖上的線程。

為什么操作線程的方法 wait、notify、notifyAll定義在了Object類中?
因為這些方法是監視器的方法,監視器其實就是鎖。
鎖可以是任意的對象,任意的對象調用的方法一定定義在Object類中。

========================================================
Lock接口
將同步和鎖封裝成了對象,并將操作鎖的方式定義到了該對象中,將隱式動作變成了顯式動作。
Lock lock=new ReentrantLock();
lock.lock();//獲取鎖
code...;//throw Exception();
lock.unlock();//釋放鎖
try
{
lock.lock();//獲取鎖
}
finally
{
lock.unlock;//釋放鎖
}

Lock接口:它的出現替代了同步代碼塊或者同步函數。將同步的隱式鎖操作變成了顯式鎖操作;
同時更為靈活,可以一個鎖上加上多組監視器。
lock();獲取鎖
unlock();釋放鎖,通常需要定義到finally代碼塊中。

Condition接口:它的出現替代了Object中的wait、notify、notifyAll方法。
將這些監視器方法單獨進行了封裝,變成了Condition監視器對象,
可以和任意鎖組合。
await();//等待
signal();//喚醒一個等待線程
signalAll();//喚醒所有等待線程

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();}
}
class Resource
{private String name;private int count = 1;private boolean flag = false;//  t1    t2private Lock lock = new ReentrantLock();private Condition condition_pro = lock.newCondition();private Condition condition_con = lock.newCondition();public  void set(String name)throws InterruptedException{lock.lock();try{while(flag)condition_pro.await();//t1,t2this.name = name+"--"+count++;System.out.println(Thread.currentThread().getName()+"...生產者.."+this.name);flag = true;condition_con.signal();}finally{lock.unlock();//釋放鎖的動作一定要執行。
        }}//  t3   t4  public  void out()throws InterruptedException{lock.lock();try{while(!flag)condition_con.await();System.out.println(Thread.currentThread().getName()+"...消費者........."+this.name);flag = false;condition_pro.signal();}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){}}}
}

===============================================================================

interrupt() 將處于強制凍結狀態的線程,恢復到運行狀態并處理InterruptedException

public class InterruptDemo {public static void main(String[] args) {Thread t = new Thread(new Demo());t.start();System.out.println("Start");t.interrupt();}
}class Demo implements Runnable{private boolean flag  = true;@Overridepublic synchronized void run() {while(flag){try {wait();} catch (InterruptedException e) {System.out.println("interrupted");flag = false;//通過修改標志位,讓線程停止
            }}System.out.println("end");}
}

=======================================================?

守護線程: t1.setDaemon(true);
t1.start();
將線程聲明為守護線程。(當前臺線程停止時,守護線程強行停止)


join:
當A線程執行到了B線程的.join()方法時,A就會等待。等B線程都執行完,A才會執行。
join可以用來臨時加入線程執行。

class Demo2 implements Runnable
{public void run(){for(int x=0; x<70; x++){System.out.println(Thread.currentThread().toString()+"....."+x);Thread.yield();}}
}public class JoinDemo
{public static void main(String[] args) throws Exception{Demo2 d = new Demo2();Thread t1 = new Thread(d);t1.start();t1.join();for(int x=0; x<40; x++){System.out.println("main....."+x);}System.out.println("over");}
}

優先級:setPriority(Thread.MAX_PRIORITY);//設置到最高優先級
線程組:每個線程屬于其創建者所在的線程組。調用線程的toString方法可以看到其線程組。

?

轉載于:https://www.cnblogs.com/grjelf/archive/2012/10/19/2726502.html

總結

以上是生活随笔為你收集整理的黑马程序员5 多线程的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。