java語言

當前位置 /首頁/計算機/java語言/列表

Java多執行緒基本使用

多執行緒是Java中不可避免的一個重要主體,下面小編為大家介紹了Java多執行緒基本使用,希望能幫到大家!

Java多執行緒基本使用

一、概念

1.程序

1.1程序:是一個正在進行中的程式,每一個程序執行都有一個執行順序,該順序是一個執行路徑,或者叫一個控制單元。

1.2執行緒:就是程序中一個獨立的控制單元,執行緒在控制著程序的執行,一個程序中至少有一個執行緒。

1.3舉例java VM:

Java VM啟動的時候會有一個程序,該程序中至少有一個執行緒在負責java程式的執行,而且這個執行緒執行的程式碼存在於main方法中,該執行緒稱之為主執行緒。擴充套件:其實更細節說明jvm,jvm啟動不止一個執行緒,還有負責垃圾回收機制的執行緒

2.多執行緒存在的意義:提高執行效率

二、多執行緒的建立

1.多執行緒建立的第一種方式,繼承Thread類

1.1定義類繼承Thread,複寫Thread類中的run方法是為了將自定義的程式碼儲存到run方法中,讓執行緒執行

1.2呼叫執行緒的start方法,該方法有兩個作用:啟動執行緒,呼叫run方法

1.3多執行緒執行的時候,執行結果每一次都不同,因為多個執行緒都獲取cpu的執行權,cpu執行到誰,誰就執行,明確一點,在某一個時刻,只能有一個程式在執行。(多核除外),cpu在做著快速的切換,以到達看上去是同時執行的效果。我們可以形象把多執行緒的執行行為在互搶cpu的執行權。這就是多執行緒的一個特性,隨機性。誰搶到,誰執行,至於執行多久,cpu說了算。

public class Demo extends Thread{

public void run(){

for (int x = 0; x < 60; x++) {

tln(ame()+"demo run---"+x);

}

}

public static void main(String[] args) {

Demo d=new Demo();//建立一個執行緒

t();//開啟執行緒,並執行該執行緒的run方法

(); //僅僅是物件呼叫方法,而執行緒建立了但並沒有執行

for (int x = 0; x < 60; x++) {

tln("Hello World---"+x);

}

}

}

2 建立多執行緒的第二種方式,步驟:

2.1定義類實現Runnable介面

2.2覆蓋Runnable介面中的run方法:將執行緒要執行的程式碼存放到run方法中

2.3.通過Thread類建立執行緒物件

2.4.將Runnable介面的子類物件作為實際引數傳遞給Thread類的建構函式

為什麼要將Runnable介面的.子類物件傳遞給Thread的建構函式:因為自定義的run方法所屬的物件是Runnable介面的子類物件,所以要讓執行緒去執行指定物件的run方法,就必須明確該run方法的所屬物件

2.5.呼叫Thread類的start方法開啟執行緒並呼叫Runnable介面子類的方法

/*

* 需求:簡易買票程式,多個視窗同時賣票

*/

public class Ticket implements Runnable {

private static int tick = 100;

Object obj = new Object();

boolean flag=true;

public void run() {

if(flag){

while (true) {

synchronized (s) {

if (tick > 0) {

tln(entThread()ame()

+ "code:" + tick--);

}

}

}

}else{

while(true){

show();

}

}

}

public static synchronized void show() {

if (tick > 0) {

tln(entThread()ame() + "show:"

+ tick--);

}

}

}

class ThisLockDemo {

public static void main(String[] args) {

Ticket t = new Ticket();

Thread t1 = new Thread(t);

try {

p(10);

} catch (Exception e) {

// TODO: handle exception

}

=false;

Thread t2 = new Thread(t);

//Thread t3 = new Thread(t);

//Thread t4 = new Thread(t);

t();

t();

//t();

//t();

}

}

3.實現方式和繼承方式有什麼區別

3.1.實現方式避免了單繼承的侷限性,在定義執行緒時建議使用實現方式

3.2.繼承Thread類:執行緒程式碼存放在Thread子類run方法中

3.3.實現Runnable:執行緒程式碼存放在介面的子類run方法中

4.多執行緒-run和start的特點

4.1為什麼要覆蓋run方法呢:

Thread類用於描述執行緒,該類定義了一個功能,用於儲存執行緒要執行的程式碼,該儲存功能就是run方法,也就是說該Thread類中的run方法,用於儲存執行緒要執行的程式碼

5.多執行緒執行狀態

建立執行緒-執行---sleep()/wait()--凍結---notify()---喚醒

建立執行緒-執行---stop()—消亡

建立執行緒-執行---沒搶到cpu執行權—臨時凍結

6.獲取執行緒物件及其名稱

6.1.執行緒都有自己預設的名稱,編號從0開始

ic Thread currentThread():獲取當前執行緒物件

ame():獲取執行緒名稱

6.4.設定執行緒名稱:setName()或者使用建構函式

public class Test extends Thread{

Test(String name){

super(name);

}

public void run(){

for (int x = 0; x < 60; x++) {

tln((entThread()==this)+"..."+ame()+" run..."+x);

}

}

}

class ThreadTest{

public static void main(String[] args) {

Test t1=new Test("one---");

Test t2=new Test("two+++");

t();

t();

();

();

for (int x = 0; x < 60; x++) {

tln("main----"+x);

}

}

}

三、多執行緒的安全問題

1.多執行緒出現安全問題的原因:

1.1.當多條語句在操作同一個執行緒共享資料時,一個執行緒對多條語句只執行了一部分,還沒有執行完,另一個執行緒參與進來執行,導致共享資料的錯誤

1.2.解決辦法:對多條操作共享資料的語句,只能讓一個執行緒都執行完,在執行過程中,其他執行緒不可以參與執行

對於多執行緒的安全問題提供了專業的解決方式,就是同步程式碼塊:

Synchronized(物件){需要被同步的程式碼},物件如同鎖,持有鎖的執行緒可以在同步中執行,沒有持有鎖的執行緒即使獲取cpu執行權,也進不去,因為沒有獲取鎖

2.同步的前提:

2.1.必須要有2個或者2個以上執行緒

2.2.必須是多個執行緒使用同一個鎖

2.3.好處是解決了多執行緒的安全問題

2.4.弊端是多個執行緒需要判斷鎖,較消耗資源

2.5.同步函式

定義同步函式,在方法錢用synchronized修飾即可

/*

* 需求:

* 銀行有一個金庫,有兩個儲戶分別存300元,每次存100元,存3次

* 目的:該程式是否有安全問題,如果有,如何解決

* 如何找問題:

* 1.明確哪些程式碼是多執行緒程式碼

* 2.明確共享資料

* 3.明確多執行緒程式碼中哪些語句是操作共享資料的

*/

public class Bank {

private int sum;

Object obj = new Object();

//定義同步函式,在方法錢用synchronized修飾即可

public synchronized void add(int n) {

//synchronized (obj) {

sumsum = sum + n;

try {

p(10);

} catch (InterruptedException e) {

// TODO Auto-generated catch block

tStackTrace();

}

tln("sum=" + sum);

//}

}

}

class Cus implements Runnable {

private Bank b = new Bank();

public void run() {

for (int x = 0; x < 3; x++) {

(100);

}

}

}

class BankDemo {

public static void main(String[] args) {

Cus c = new Cus();

Thread t1 = new Thread(c);

Thread t2 = new Thread(c);

t();

t();

}

}

6.同步的鎖

6.1函式需要被物件呼叫,那麼函式都有一個所屬物件引用,就是this.,所以同步函式使用的鎖是this

6.2.靜態函式的鎖是class物件

靜態進記憶體時,記憶體中沒有本類物件,但是一定有該類對應的位元組碼檔案物件,類名s,該物件的型別是Class

6.3.靜態的同步方法,使用的鎖是該方法所在類的位元組碼檔案物件,類名s

/*

* 需求:簡??買票程式,多個視窗同時賣票

*/

public class Ticket implements Runnable {

private static int tick = 100;

Object obj = new Object();

boolean flag=true;

public void run() {

if(flag){

while (true) {

synchronized (s) {

if (tick > 0) {

tln(entThread()ame()

+ "code:" + tick--);

}

}

}

}else{

while(true){

show();

}

}

}

public static synchronized void show() {

if (tick > 0) {

tln(entThread()ame() + "show:"

+ tick--);

}

}

}

class ThisLockDemo {

public static void main(String[] args) {

Ticket t = new Ticket();

Thread t1 = new Thread(t);

try {

p(10);

} catch (Exception e) {

// TODO: handle exception

}

=false;

Thread t2 = new Thread(t);

//Thread t3 = new Thread(t);

//Thread t4 = new Thread(t);

t();

t();

//t();

//t();

}

}

7.多執行緒,單例模式-懶漢式

懶漢式與餓漢式的區別:懶漢式能延遲例項的載入,如果多執行緒訪問時,懶漢式會出現安全問題,可以使用同步來解決,用同步函式和同步程式碼都可以,但是比較低效,用雙重判斷的形式能解決低效的問題,加同步的時候使用的鎖是該類鎖屬的位元組碼檔案物件

8.多執行緒-死鎖

同步中巢狀同步會出現死鎖

TAG標籤:多執行緒 JAVA #