日韩av黄I国产麻豆传媒I国产91av视频在线观看I日韩一区二区三区在线看I美女国产在线I麻豆视频国产在线观看I成人黄色短片

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 >

2019-06-03 Java学习日记 day24 多线程

發布時間:2025/5/22 65 豆豆
生活随笔 收集整理的這篇文章主要介紹了 2019-06-03 Java学习日记 day24 多线程 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

多線程

  線程是程序執行的一臺路徑,一個進程中可以包含多條線程

  多線程并發執行可以提高程序的效率,可以同時完成多項工作

多線程的應用背景

  紅蜘蛛同時共享屏幕給多個電腦

  迅雷開啟多條線程一起下載

  QQ同時和多個人一起視頻

  服務器同時處理多個客戶端請求

?

多線程并行和并發

  并行就是兩個任務同時運行,就是甲任務進行的同時,乙任務也在進行(需要多核CPU)

  并發是指兩個任務都請求運行,而處理器只能接受一個任務,就把這兩個任務輪流進行,由于時間間隔較短,使人感覺兩個任務都在運行

  比如我跟兩個網友聊天,左手操作一個電腦跟甲聊,同時右手用另一臺電腦跟乙聊天,這就叫并行

  如果用一臺電腦我先給甲發個信息,然后立刻再給乙發信息,然后再跟甲聊,再跟乙聊。這就叫并發

?

java程序運行原理和jvm的啟動

  *java命令啟動java虛擬機,啟動jvm,等于啟動了一個應用程序,也就是啟動了一個進程,該進程會自動啟動一個 “ 主線程 ”,然后主線程去調用某個類的 main 方法

?

  *jvm啟動至少啟動了垃圾回收線程和主線程,所以是多線程的

?

多線程程序實現

 1. 繼承Thread

    定義類繼承Thread

    重寫run方法

    把新線程要做的是寫在run方法中

    創建線程對象

    開啟新線程,內部會自動執行run方法

public class demo1_thread {public static void main(String[] args) {mythread mt1 =new mythread(); //創建thread類的子類對象mt1.start(); //開啟線程for(int i=0;i<1000;i++){System.out.println("bbbbb");}}} class mythread extends Thread{ //繼承threadpublic void run(){ //重寫run方法for(int i=0;i<1000;i++){System.out.println("aaaaaaaaaa");}} } 案例

?

 2. 實現runnable

    定義類顯示Runnable接口

    實現run方法

    把新線程要做的事寫在run方法中

    創建自定義的Runnable的子類對象

    創建Thread對象,傳入Runnable

    調用start()開啟新線程,內部會自動調用Runnable的run方法

public class demo2_Runnnbale {public static void main (String args []){myrunnbale mr =new myrunnbale(); //創建runnable的子類對象new Thread(mr).start(); //將其當做參數傳遞給thread的構造函數,并開啟線程for (int i = 0; i < 1000; i++) {System.out.println("cc");}} } class myrunnbale implements Runnable{@Overridepublic void run() {for (int i = 0; i < 1000; i++) {System.out.println("aaaaaaaaaaaaaa");}}} 案例

實現Runnable的原理

  看Thread類的構造函數,傳遞了Runnable接口的引用

  通過init()方法找到傳遞的target給成員變量的target賦值

  查看run方法,發現run方法中有判斷,如果target不為null就會太哦用Runnable接口子類對象的run方法

?

兩種方式的區別

  1.繼承Thread:由于子類重寫了Thread類的run(),方太哦用start()時,直接找子類的run()方法

  2.實現Runnable:構造函數中傳入了Runnable的引用,成員變量記住了它,start()調用run()方法時內部成員變量Runnable引用是否為空,不為空編譯時看的siRunnable的run(),運行時執行的獅子類的run()方法

?

繼承Thread:

  好處是:可以直接使用Thread類中的方法,代碼簡單

  弊端是:如果已經有父類,就不能用這種方法

實現Runnable接口:

  好處是:即使自己定義的縣城類有了父類也沒關系,因為有了父類也可以實現接口,而且接口是可以多實現的

  弊端是:不能直接使用Thread中的方法需要先獲取到線程對象后,才能得到Thread的方法,代碼復雜

?

匿名內部類實現線程

  1.繼承Thread方法 

  2.實現Runnable方法

public class demo3_Thread {public static void main(String[] args) {new Thread(){ //繼承Thread方法public void run(){ //重寫run方法for (int i = 0; i < 3000; i++) {System.out.println("aaaaaaaaa");}}}.start(); //開啟線程new Thread(new Runnable(){public void run(){for (int i = 0; i < 3000; i++) {System.out.println("bbb");}}}).start();}} 案例

?

獲取名字

  1.通過geyName()方法獲取線程對象的名字

設置名字

  2.通過構造方法函數可以傳入String類型的名字

?

  通過setName(String)方法可以設置線程對象的名字

public class demo1_Name {public static void main (String args[]){new Thread("大哥"){public void run(){System.out.println(this.getName()+"aaaaaaaa");}}.start();new Thread(){public void run(){this.setName("戰三");System.out.println(this.getName()+"bb");}}.start();Thread t1= new Thread("大哥"){public void run(){System.out.println(this.getName()+"aaaaaaaa");}};t1.setName("李");t1.start();} } 案例

?

獲取當前線程的對象

  Thread.currentThread(),主線程也可以獲取

public class demo2_currentthread {public static void main(String[] args) {new Thread("毛毛"){public void run (){System.out.println(getName()+"...aaaaaaa");}}.start();new Thread(new Runnable(){public void run(){//Thread.currentThread()獲取當前正在執行的線程System.out.println(Thread.currentThread().getName()+"...bb");}}).start();Thread.currentThread().setName("主線程");System.out.println(Thread.currentThread().getName());}} 案例

?

休眠線程

  Thread.sleep(毫秒,納秒),控制當前線程休眠若干毫秒1秒 =1000 * 1000 * 1000納秒? 1000000000

public class demo3_seelp {public static void main(String[] args) throws InterruptedException {//demo1();new Thread(){public void run(){for (int i = 20; i >=0; i--) {try {Thread.sleep(1000);} catch (InterruptedException e) {// TODO Auto-generated catch block e.printStackTrace();}System.out.println(getName()+"...a");}}}.start();new Thread(){public void run(){for (int i = 20; i >=0; i--) {try {Thread.sleep(1000);} catch (InterruptedException e) {// TODO Auto-generated catch block e.printStackTrace();}System.out.println(getName()+"..bb");}}}.start();}public static void demo1() throws InterruptedException {for(int i=20;i>=0;i--){Thread.sleep(1000);System.out.println("倒計時"+i+"秒");}}} 案例

?

守護線程

  setDaemon(),設置一個線程為守護線程,該線程不會單獨執行,當其他飛守護線程都執行結束后,自動退出

public class demo4_daemon {public static void main(String[] args) {Thread t1 =new Thread(){public void run(){for (int i = 0; i < 2; i++) {System.out.println(getName()+"..aaaaaaaa");}}};Thread t2 =new Thread(){public void run(){for (int i = 0; i < 50; i++) {System.out.println(getName()+"..bb");}}};t2.setDaemon(true); //當傳入true就是意味著設置為守護線程 t1.start();t2.start();}} 案例

?

加入線程

  join(),當前線程暫停,等待指定的線程執行結束后,當前線程在繼續

  join(int),可以等待指定的毫秒之后繼續

public class demo5_Join {public static void main(String[] args) {final Thread t1 =new Thread(){public void run (){for(int i=0; i<10 ;i++){System.out.println(getName()+"...aaaaaaaaa");}}};Thread t2 =new Thread(){public void run (){for(int i=0; i<10 ;i++){if(i==2){try {t1.join(1);} catch (InterruptedException e) {e.printStackTrace();}}System.out.println(getName()+"...bb");}}};t1.start();t2.start();}} 案例

?

禮讓線程

yield讓出cpu

?

設置線程的優先級

  setPriority() 設置線程的優先級

N1.setPriority(Thread.MIN_PRIORITY);? ? ? ? ? ? //設置最大的線程優先級
N2.setPriority(Thread.MAX_PRIORITY);? ? ? ? ? ?//設置最小線程優先級

?

同步代碼塊

什么情況下需要同步

  當多線程并發,有多段代碼同時執行是,我們希望某一段代碼執行的過程中cpu不要切換到其他線程工作,這是就需要同步

  如果兩端代碼是同步的,那么同一時間值執行一段,在一段代碼每執行結束之前,不會執行另一端代碼

同步代碼塊

  使用synchronized關鍵字加上一個鎖對象來定義一段代碼,這就叫同步代碼塊

  多個同步代碼塊如果使用相同的鎖對象,那么他們就是同步的

public class test_sybchronized {public static void main(String[] args) {final pritner p1=new pritner();new Thread(){public void run(){while(true){p1.print1(); }}}.start();new Thread(){public void run(){while(true){p1.print2(); }}}.start();}} class pritner{ demo d=new demo();public void print1(){synchronized (d) {System.out.println("學習");}}public void print2(){System.out.println("學校");} }class demo{} 案例

?

同步方法

*使用synchronized 關鍵字修飾一個方法,該方法中所有的代碼都是同步的

public class test2_sybchronized {public static void main(String[] args) {final pritner2 p1=new pritner2();new Thread(){public void run(){while(true){p1.print1(); }}}.start();new Thread(){public void run(){while(true){p1.print2(); }}}.start();}} class pritner2{//非靜態放入同步方法的鎖對象是this//靜態的鎖不方法的鎖對象是:該類的字節碼對象public synchronized void print1(){System.out.print("學");System.out.print("習");System.out.print("的");System.out.print("心");System.out.print("\r\n");}public void print2(){synchronized (this) { System.out.print("學");System.out.print("校");System.out.print("的");System.out.print("路");System.out.print("上");System.out.print("\r\n");}}} 案例

?

線程安全問題

  多線程并發操作同一數據時,就有可能出現線程安全問題

  使用同步技術可以解決這種問題,把操作數據的代碼進行同步,不要多個線程一起操作

public class test2_ticket {public static void main(String[] args) {new ticket().start();new ticket().start();new ticket().start();new ticket().start();}} class ticket extends Thread{private static int ticket =100;public void run(){while(true){synchronized (ticket.class) { if(ticket <=0){break;}try {Thread.sleep(10);} catch (InterruptedException e) {// TODO Auto-generated catch block e.printStackTrace();}System.out.println(getName() + "...這是第" + ticket-- + "號票");}}} } 案例

?

死鎖

多線程同步的時候,如果同步代碼嵌套,使用相同鎖,就有可能出現死鎖

public class test3_ {private static String s1 ="筷子左";private static String s2 ="筷子右";public static void main(String[] args) {new Thread(){public void run (){while(true){synchronized (s1) {System.out.println(getName()+"讀取"+s1+"等待"+s2); synchronized (s2) {System.out.println(getName()+"拿到"+s2+"吃"); }}}}}.start();new Thread(){public void run (){while(true){synchronized (s2) {System.out.println(getName()+"讀取"+s2+"等待"+s1); synchronized (s1) {System.out.println(getName()+"拿到"+s1+"吃"); }}}}}.start();}} 案例

?

轉載于:https://www.cnblogs.com/JungTan0113/p/10970951.html

總結

以上是生活随笔為你收集整理的2019-06-03 Java学习日记 day24 多线程的全部內容,希望文章能夠幫你解決所遇到的問題。

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