最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

java必學(xué)必會(huì)之線程(1)

 更新時(shí)間:2015年12月03日 11:20:20   作者:孤傲蒼狼  
java必學(xué)必會(huì)之線程第一篇,介紹了線程的基本概念、線程的創(chuàng)建和啟動(dòng),想要學(xué)好java線程的朋友一定要好好閱讀這篇文章

一、線程的基本概念

  

線程理解:線程是一個(gè)程序里面不同的執(zhí)行路徑

  每一個(gè)分支都叫做一個(gè)線程,main()叫做主分支,也叫主線程。

  程只是一個(gè)靜態(tài)的概念,機(jī)器上的一個(gè).class文件,機(jī)器上的一個(gè).exe文件,這個(gè)叫做一個(gè)進(jìn)程。程序的執(zhí)行過程都是這樣的:首先把程序的代碼放到內(nèi)存的代碼區(qū)里面,代碼放到代碼區(qū)后并沒有馬上開始執(zhí)行,但這時(shí)候說明了一個(gè)進(jìn)程準(zhǔn)備開始,進(jìn)程已經(jīng)產(chǎn)生了,但還沒有開始執(zhí)行,這就是進(jìn)程,所以進(jìn)程其實(shí)是一個(gè)靜態(tài)的概念,它本身就不能動(dòng)。平常所說的進(jìn)程的執(zhí)行指的是進(jìn)程里面主線程開始執(zhí)行了,也就是main()方法開始執(zhí)行了。進(jìn)程是一個(gè)靜態(tài)的概念,在我們機(jī)器里面實(shí)際上運(yùn)行的都是線程。

  Windows操作系統(tǒng)是支持多線程的,它可以同時(shí)執(zhí)行很多個(gè)線程,也支持多進(jìn)程,因此Windows操作系統(tǒng)是支持多線程多進(jìn)程的操作系統(tǒng)。Linux和Uinux也是支持多線程和多進(jìn)程的操作系統(tǒng)。DOS就不是支持多線程和多進(jìn)程了,它只支持單進(jìn)程,在同一個(gè)時(shí)間點(diǎn)只能有一個(gè)進(jìn)程在執(zhí)行,這就叫單線程。

  CPU難道真的很神通廣大,能夠同時(shí)執(zhí)行那么多程序嗎?不是的,CPU的執(zhí)行是這樣的:CPU的速度很快,一秒鐘可以算好幾億次,因此CPU把自己的時(shí)間分成一個(gè)個(gè)小時(shí)間片,我這個(gè)時(shí)間片執(zhí)行你一會(huì),下一個(gè)時(shí)間片執(zhí)行他一會(huì),再下一個(gè)時(shí)間片又執(zhí)行其他人一會(huì),雖然有幾十個(gè)線程,但一樣可以在很短的時(shí)間內(nèi)把他們通通都執(zhí)行一遍,但對(duì)我們?nèi)藖碚f,CPU的執(zhí)行速度太快了,因此看起來就像是在同時(shí)執(zhí)行一樣,但實(shí)際上在一個(gè)時(shí)間點(diǎn)上,CPU只有一個(gè)線程在運(yùn)行。

學(xué)習(xí)線程首先要理清楚三個(gè)概念

1、進(jìn)程:進(jìn)程是一個(gè)靜態(tài)的概念
2、線程:一個(gè)進(jìn)程里面有一個(gè)主線程叫main()方法,是一個(gè)程序里面的,一個(gè)進(jìn)程里面不同的執(zhí)行路徑。
3、在同一個(gè)時(shí)間點(diǎn)上,一個(gè)CPU只能支持一個(gè)線程在執(zhí)行。因?yàn)镃PU運(yùn)行的速度很快,因此我們看起來的感覺就像是多線程一樣。
  什么才是真正的多線程?如果你的機(jī)器是雙CPU,或者是雙核,這確確實(shí)實(shí)是多線程。

二、線程的創(chuàng)建和啟動(dòng)

  

  在JAVA里面,JAVA的線程是通過java.lang.Thread類來實(shí)現(xiàn)的,每一個(gè)Thread對(duì)象代表一個(gè)新的線程。創(chuàng)建一個(gè)新線程出來有兩種方法:第一個(gè)是從Thread類繼承,另一個(gè)是實(shí)現(xiàn)接口runnable。VM啟動(dòng)時(shí)會(huì)有一個(gè)由主方法(public static void main())所定義的線程,這個(gè)線程叫主線程??梢酝ㄟ^創(chuàng)建Thread的實(shí)例來創(chuàng)建新的線程。你只要new一個(gè)Thread對(duì)象,一個(gè)新的線程也就出現(xiàn)了。每個(gè)線程都是通過某個(gè)特定的Thread對(duì)象所對(duì)應(yīng)的方法run()來完成其操作的,方法run()稱為線程體。

范例1:使用實(shí)現(xiàn)Runnable接口創(chuàng)建和啟動(dòng)新線程

開辟一個(gè)新的線程來調(diào)用run方法

package cn.galc.test;

public class TestThread1{
 public static void main(String args[]){
 Runner1 r1 = new Runner1();//這里new了一個(gè)線程類的對(duì)象出來
 //r1.run();//這個(gè)稱為方法調(diào)用,方法調(diào)用的執(zhí)行是等run()方法執(zhí)行完之后才會(huì)繼續(xù)執(zhí)行main()方法
 Thread t = new Thread(r1);//要啟動(dòng)一個(gè)新的線程就必須new一個(gè)Thread對(duì)象出來
 //這里使用的是Thread(Runnable target) 這構(gòu)造方法
 t.start();//啟動(dòng)新開辟的線程,新線程執(zhí)行的是run()方法,新線程與主線程會(huì)一起并行執(zhí)行
 for(int i=0;i<10;i++){
  System.out.println("maintheod:"+i);
 }
 }
}
/*定義一個(gè)類用來實(shí)現(xiàn)Runnable接口,實(shí)現(xiàn)Runnable接口就表示這個(gè)類是一個(gè)線程類*/
class Runner1 implements Runnable{
 public void run(){
 for(int i=0;i<10;i++){
  System.out.println("Runner1:"+i);
 }
 }
}


多線程程序執(zhí)行的過程如下所示:

 

不開辟新線程直接調(diào)用run方法

 

運(yùn)行結(jié)果如下:

 范例2:繼承Thread類,并重寫其run()方法創(chuàng)建和啟動(dòng)新的線程

package cn.galc.test;

/*線程創(chuàng)建與啟動(dòng)的第二種方法:定義Thread的子類并實(shí)現(xiàn)run()方法*/
public class TestThread2{
 public static void main(String args[]){
 Runner2 r2 = new Runner2();
 r2.start();//調(diào)用start()方法啟動(dòng)新開辟的線程
 for(int i=0;i<=10;i++){
  System.out.println("mainMethod:"+i);
 }
 }
}
/*Runner2類從Thread類繼承
通過實(shí)例化Runner2類的一個(gè)對(duì)象就可以開辟一個(gè)新的線程
調(diào)用從Thread類繼承來的start()方法就可以啟動(dòng)新開辟的線程*/
class Runner2 extends Thread{
 public void run(){//重寫run()方法的實(shí)現(xiàn)
 for(int i=0;i<=10;i++){
  System.out.println("Runner2:"+i);
 }
 }
}

  使用實(shí)現(xiàn)Runnable接口和繼承Thread類這兩種開辟新線程的方法的選擇應(yīng)該優(yōu)先選擇實(shí)現(xiàn)Runnable接口這種方式去開辟一個(gè)新的線程。因?yàn)榻涌诘膶?shí)現(xiàn)可以實(shí)現(xiàn)多個(gè),而類的繼承只能是單繼承。因此在開辟新線程時(shí)能夠使用Runnable接口就盡量不要使用從Thread類繼承的方式來開辟新的線程。

三、線程狀態(tài)轉(zhuǎn)換

  

3.1.線程控制的基本方法

  

3.2. sleep/join/yield方法介紹

  

sleep方法的應(yīng)用范例:

package cn.galc.test;

import java.util.*;

public class TestThread3 {
 public static void main(String args[]){
 MyThread thread = new MyThread();
 thread.start();//調(diào)用start()方法啟動(dòng)新開辟的線程
 try {
  /*Thread.sleep(10000);
  sleep()方法是在Thread類里面聲明的一個(gè)靜態(tài)方法,因此可以使用Thread.sleep()的格式進(jìn)行調(diào)用
  */
  /*MyThread.sleep(10000);
  MyThread類繼承了Thread類,自然也繼承了sleep()方法,所以也可以使用MyThread.sleep()的格式進(jìn)行調(diào)用
  */
  /*靜態(tài)方法的調(diào)用可以直接使用“類名.靜態(tài)方法名”
  或者“對(duì)象的引用.靜態(tài)方法名”的方式來調(diào)用*/
  MyThread.sleep(10000);
  System.out.println("主線程睡眠了10秒種后再次啟動(dòng)了");
  //在main()方法里面調(diào)用另外一個(gè)類的靜態(tài)方法時(shí),需要使用“靜態(tài)方法所在的類.靜態(tài)方法名”這種方式來調(diào)用
  /*
  所以這里是讓主線程睡眠10秒種
  在哪個(gè)線程里面調(diào)用了sleep()方法就讓哪個(gè)線程睡眠,所以現(xiàn)在是主線程睡眠了。
  */
 } catch (InterruptedException e) {
  e.printStackTrace();
 }
 //thread.interrupt();//使用interrupt()方法去結(jié)束掉一個(gè)線程的執(zhí)行并不是一個(gè)很好的做法
 thread.flag=false;//改變循環(huán)條件,結(jié)束死循環(huán)
 /**
  * 當(dāng)發(fā)生InterruptedException時(shí),直接把循環(huán)的條件設(shè)置為false即可退出死循環(huán),
  * 繼而結(jié)束掉子線程的執(zhí)行,這是一種比較好的結(jié)束子線程的做法
  */
 /**
  * 調(diào)用interrupt()方法把正在運(yùn)行的線程打斷
 相當(dāng)于是主線程一盆涼水潑上去把正在執(zhí)行分線程打斷了
 分線程被打斷之后就會(huì)拋InterruptedException異常,這樣就會(huì)執(zhí)行return語句返回,結(jié)束掉線程的執(zhí)行
 所以這里的分線程在執(zhí)行完10秒鐘之后就結(jié)束掉了線程的執(zhí)行
  */
 }
}

class MyThread extends Thread {
 boolean flag = true;// 定義一個(gè)標(biāo)記,用來控制循環(huán)的條件

 public void run() {
 /*
  * 注意:這里不能在run()方法的后面直接寫throw Exception來拋異常, 
  * 因?yàn)楝F(xiàn)在是要重寫從Thread類繼承而來的run()方法,重寫方法不能拋出比被重寫的方法的不同的異常。
  * 所以這里只能寫try……catch()來捕獲異常
  */
 while (flag) {
  System.out.println("==========" + new Date().toLocaleString() + "===========");
  try {
  /*
   * 靜態(tài)方法的調(diào)用格式一般為“類名.方法名”的格式去調(diào)用 在本類中聲明的靜態(tài)方法時(shí)調(diào)用時(shí)直接寫靜態(tài)方法名即可。 當(dāng)然使用“類名.方法名”的格式去調(diào)用也是沒有錯(cuò)的
   */
  // MyThread.sleep(1000);//使用“類名.方法名”的格式去調(diào)用屬于本類的靜態(tài)方法
  sleep(1000);//睡眠的時(shí)如果被打斷就會(huì)拋出InterruptedException異常
  // 這里是讓這個(gè)新開辟的線程每隔一秒睡眠一次,然后睡眠一秒鐘后再次啟動(dòng)該線程
  // 這里在一個(gè)死循環(huán)里面每隔一秒啟動(dòng)一次線程,每個(gè)一秒打印出當(dāng)前的系統(tǒng)時(shí)間
  } catch (InterruptedException e) {
  /*
   * 睡眠的時(shí)一盤冷水潑過來就有可能會(huì)打斷睡眠 
   * 因此讓正在運(yùn)行線程被一些意外的原因中斷的時(shí)候有可能會(huì)拋被打擾中斷(InterruptedException)的異常
   */
  return;
  // 線程被中斷后就返回,相當(dāng)于是結(jié)束線程
  }
 }
 }
}

運(yùn)行結(jié)果:

 join方法的使用范例:

package cn.galc.test;

public class TestThread4 {
 public static void main(String args[]) {
 MyThread2 thread2 = new MyThread2("mythread");
 // 在創(chuàng)建一個(gè)新的線程對(duì)象的同時(shí)給這個(gè)線程對(duì)象命名為mythread
 thread2.start();// 啟動(dòng)線程
 try {
  thread2.join();// 調(diào)用join()方法合并線程,將子線程mythread合并到主線程里面
  // 合并線程后,程序的執(zhí)行的過程就相當(dāng)于是方法的調(diào)用的執(zhí)行過程
 } catch (InterruptedException e) {
  e.printStackTrace();
 }
 for (int i = 0; i <= 5; i++) {
  System.out.println("I am main Thread");
 }
 }
}

class MyThread2 extends Thread {
 MyThread2(String s) {
 super(s);
 /*
  * 使用super關(guān)鍵字調(diào)用父類的構(gòu)造方法 
  * 父類Thread的其中一個(gè)構(gòu)造方法:“public Thread(String name)” 
  * 通過這樣的構(gòu)造方法可以給新開辟的線程命名,便于管理線程
  */
 }

 public void run() {
 for (int i = 1; i <= 5; i++) {
  System.out.println("I am a\t" + getName());
  // 使用父類Thread里面定義的
  //public final String getName(),Returns this thread's name.
  try {
  sleep(1000);// 讓子線程每執(zhí)行一次就睡眠1秒鐘
  } catch (InterruptedException e) {
  return;
  }
 }
 }
}

運(yùn)行結(jié)果:

yield方法的使用范例:

package cn.galc.test;

public class TestThread5 {
 public static void main(String args[]) {
 MyThread3 t1 = new MyThread3("t1");
 /* 同時(shí)開辟了兩條子線程t1和t2,t1和t2執(zhí)行的都是run()方法 */
 /* 這個(gè)程序的執(zhí)行過程中總共有3個(gè)線程在并行執(zhí)行,分別為子線程t1和t2以及主線程 */
 MyThread3 t2 = new MyThread3("t2");
 t1.start();// 啟動(dòng)子線程t1
 t2.start();// 啟動(dòng)子線程t2
 for (int i = 0; i <= 5; i++) {
  System.out.println("I am main Thread");
 }
 }
}

class MyThread3 extends Thread {
 MyThread3(String s) {
 super(s);
 }

 public void run() {
 for (int i = 1; i <= 5; i++) {
  System.out.println(getName() + ":" + i);
  if (i % 2 == 0) {
  yield();// 當(dāng)執(zhí)行到i能被2整除時(shí)當(dāng)前執(zhí)行的線程就讓出來讓另一個(gè)在執(zhí)行run()方法的線程來優(yōu)先執(zhí)行
  /*
   * 在程序的運(yùn)行的過程中可以看到,
   * 線程t1執(zhí)行到(i%2==0)次時(shí)就會(huì)讓出線程讓t2線程來優(yōu)先執(zhí)行 
   * 而線程t2執(zhí)行到(i%2==0)次時(shí)也會(huì)讓出線程給t1線程優(yōu)先執(zhí)行
   */
  }
 }
 }
}

運(yùn)行結(jié)果如下:

 以上就是本文的全部內(nèi)容,對(duì)java線程進(jìn)行全面學(xué)習(xí),希望可以幫助到大家。

相關(guān)文章

  • Java依賴注入容器超詳細(xì)全面講解

    Java依賴注入容器超詳細(xì)全面講解

    依賴注入(Dependency Injection)和控制反轉(zhuǎn)(Inversion of Control)是同一個(gè)概念。具體含義是:當(dāng)某個(gè)角色(可能是一個(gè)Java實(shí)例,調(diào)用者)需要另一個(gè)角色(另一個(gè)Java實(shí)例,被調(diào)用者)的協(xié)助時(shí),在 傳統(tǒng)的程序設(shè)計(jì)過程中,通常由調(diào)用者來創(chuàng)建被調(diào)用者的實(shí)例
    2023-01-01
  • SpringBoot中引入MyBatisPlus的常規(guī)操作

    SpringBoot中引入MyBatisPlus的常規(guī)操作

    這篇文章主要介紹了SpringBoot中引入MyBatisPlus的常規(guī)操作,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-11-11
  • java分布式面試接口如何保證冪等及概念理解

    java分布式面試接口如何保證冪等及概念理解

    這篇文章主要為大家介紹了java分布式面試中接口如何保證冪等的問題解答以及概念描述,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步
    2022-03-03
  • Java源碼解析之ClassLoader

    Java源碼解析之ClassLoader

    在看系統(tǒng)啟動(dòng)的流程中看到了ClassLoader使用,重新溫故下ClassLoader流程和原理,文中有非常詳細(xì)的代碼示例,對(duì)正在學(xué)習(xí)java的小伙伴們很有幫助,需要的朋友可以參考下
    2021-05-05
  • 詳細(xì)解析Java中抽象類和接口的區(qū)別

    詳細(xì)解析Java中抽象類和接口的區(qū)別

    這篇文章主要介紹了Java中抽象類和接口的區(qū)別詳解,需要的朋友可以參考下
    2014-10-10
  • IDEA SSM整合Redis項(xiàng)目實(shí)例 附源碼

    IDEA SSM整合Redis項(xiàng)目實(shí)例 附源碼

    今天給大家普及IDEA SSM整合Redis項(xiàng)目實(shí)例,包括pom.xml 配置和spring-redis.xml 配置代碼,代碼也很簡單,通過項(xiàng)目實(shí)際案例能更好的幫助大家理解,需要的朋友可以參考下
    2021-06-06
  • java如何使用zip壓縮實(shí)現(xiàn)讀取寫入

    java如何使用zip壓縮實(shí)現(xiàn)讀取寫入

    這篇文章主要為大家介紹了java如何使用zip壓縮實(shí)現(xiàn)讀取寫入示例,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-11-11
  • Java多線程中的wait/notify通信模式實(shí)例詳解

    Java多線程中的wait/notify通信模式實(shí)例詳解

    這篇文章主要給大家介紹了關(guān)于Java多線程中wait/notify通信模式的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-12-12
  • 解決JAVA非對(duì)稱加密不同系統(tǒng)加密結(jié)果不一致的問題

    解決JAVA非對(duì)稱加密不同系統(tǒng)加密結(jié)果不一致的問題

    這篇文章主要介紹了解決JAVA非對(duì)稱加密不同系統(tǒng)加密結(jié)果不一致的問題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧
    2020-10-10
  • 解決@Cacheable在同一個(gè)類中方法調(diào)用不起作用的問題

    解決@Cacheable在同一個(gè)類中方法調(diào)用不起作用的問題

    這篇文章主要介紹了解決@Cacheable在同一個(gè)類中方法調(diào)用不起作用的問題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-07-07

最新評(píng)論

乡城县| 桐城市| 慈利县| 青龙| 垦利县| 洛川县| 平泉县| 枣强县| 广东省| 肇东市| 江陵县| 麦盖提县| 普兰店市| 兴海县| 临城县| 沽源县| 修武县| 富阳市| 横峰县| 徐水县| 尼勒克县| 卓资县| 大名县| 津市市| 磐安县| 琼结县| 台州市| 合阳县| 新田县| 陆丰市| 那曲县| 五峰| 桐乡市| 碌曲县| 绥中县| 隆尧县| 乌鲁木齐市| 克拉玛依市| 铅山县| 长宁区| 长治县|