2017-12-27?多線程-thread

多線程-thread

Thread類和Runnable接口都在java.lang包中。

內(nèi)容:

1.多線程的基本概念

2.創(chuàng)建線程

3.實(shí)例-龜兔賽跑

4.線程之間的數(shù)據(jù)交流

5.線程調(diào)度

6.線程的基本控制(暫放,這里的實(shí)例是賣票那個(gè)例子)

7.線程同步(synchronized 標(biāo)記)

實(shí)現(xiàn)線程同步化需要使用synchronized 關(guān)鍵字

8.線程死鎖



1.多線程的概念

java 語(yǔ)言支持多線程技術(shù)。(multithreaded programing)

為什么要有多線程?

是在編程時(shí),會(huì)遇到多個(gè)用戶的請(qǐng)求,為了更好地響應(yīng)多個(gè)用戶的請(qǐng)求,并及時(shí)作出響應(yīng)。

(1)線程的概念

先介紹進(jìn)程和多進(jìn)程的概念,再介紹線程的概念。

1.1 什么叫做進(jìn)程?進(jìn)程是程序的一次動(dòng)態(tài)的執(zhí)行過(guò)程,經(jīng)歷了代碼開(kāi)始到執(zhí)行完畢的一個(gè)完整過(guò)程。多進(jìn)程操作系統(tǒng)能并發(fā)運(yùn)行多個(gè)進(jìn)程。

并發(fā)運(yùn)行實(shí)際上是交叉運(yùn)行。

因?yàn)橛?jì)算機(jī)某個(gè)時(shí)刻只能執(zhí)行一個(gè)任務(wù),

因此多進(jìn)程是指多個(gè)進(jìn)程交叉運(yùn)行,給人的感覺(jué)好像是同時(shí)運(yùn)行的。

什么叫線程?

線程是由進(jìn)程派發(fā)的,是比進(jìn)程更小的執(zhí)行單位。

多線程是指在單個(gè)程序(或進(jìn)程)中同時(shí)運(yùn)行多個(gè)線程完成不同的工作,這些線程可以同時(shí)存在、同時(shí)運(yùn)行,形成多條執(zhí)行線程。如下圖所示。


線程與進(jìn)程也有共同點(diǎn)和不同點(diǎn)之處。

共同點(diǎn):實(shí)現(xiàn)并發(fā)的一個(gè)基本單位,都要系統(tǒng)進(jìn)行調(diào)度以提高運(yùn)行效率。

不同點(diǎn):(1)線程是比進(jìn)程更小的執(zhí)行單位;

? ? ? ? ? ? ? (2)每個(gè)進(jìn)程都有一個(gè)專門的內(nèi)存區(qū)域,而線程卻共享內(nèi)存單元,線程是通過(guò)共享的內(nèi)存單元來(lái)實(shí)現(xiàn)數(shù)據(jù)交換、實(shí)時(shí)通信等操作。

(2)線程的狀態(tài)與生命周期


思考:當(dāng)線程的run()方法運(yùn)行完成,線程就轉(zhuǎn)到(死亡)狀態(tài)。


用程序進(jìn)行解釋線程的狀態(tài)與生命周期:

(1)主類中創(chuàng)建新線程對(duì)象,并且start().

(2)在創(chuàng)建的非主類中進(jìn)行寫方法run().

class Thread1 extends Thread{

//3.(運(yùn)行狀態(tài))? 一 一種是4.死亡狀態(tài),一種是5.阻塞狀態(tài)(sleep(),wait(),join().)

? public void run(){

? ? ? ? 線程的任務(wù)

? }

}

public class Test1{

//主進(jìn)程 ,即main()方法。

? public static void main(String [] argps){

? ? ? ? Thread1 th = new Thread1(); //創(chuàng)建新線程的實(shí)例化對(duì)象。1.(新建狀態(tài))

? ? ? ? th.start();//2.(就緒狀態(tài))

}

}

在一個(gè)系統(tǒng)中,任何時(shí)刻最多只有一個(gè)運(yùn)行態(tài)線程。

sleep(),yield(),wait(),join()四個(gè)方法的定義和區(qū)別?

2.創(chuàng)建線程

(1)創(chuàng)建線程有兩種方式:

? ? ? 1.通過(guò)繼承Thread類創(chuàng)建線程。(喜歡用這個(gè))

? ? ? ? 2.通過(guò)實(shí)現(xiàn)Runnable接口創(chuàng)建線程。

是否在任何情況下都能用任何一種方式創(chuàng)建線程?

注:(1)Thread類和Runnable接口都在java.lang包中。

? ? ? ? ? (2)? 創(chuàng)建新線程必須有run()方法。

解釋:

Runnable接口:在這個(gè)接口中只定義了run()方法,這個(gè)方法是線程執(zhí)行的主體,在線程獲取CPY時(shí)間運(yùn)行時(shí),就是自動(dòng)執(zhí)行線程的run()方法,因此,新的線程要完成的任務(wù)流程應(yīng)該寫在run()方法中,所以創(chuàng)建新線程就必須有run()方法。創(chuàng)建線程時(shí),可以通過(guò)實(shí)現(xiàn)Runnable接口獲取run()方法。

Thread類:這個(gè)類是已經(jīng)實(shí)現(xiàn)了Runnable接口的類,在這個(gè)類中除了擁有run()方法,還提高了對(duì)線程操作的方法,因此可以通過(guò)繼承Thread類創(chuàng)建新線程。


1.通過(guò)繼承Thread類創(chuàng)建線程


Thread類格式:

pulic class Thread extends Object implements Runnable

實(shí)例:

ThreadTest.java

package Thread;

/*步驟:

(1)主類中創(chuàng)建新線程對(duì)象,并且start().

(2)在創(chuàng)建的非主類中繼承Thread類進(jìn)行寫方法run().

*/

//通過(guò)繼承Thread類創(chuàng)建新線程

class Thread1 extends Thread{

//3.那么就開(kāi)始執(zhí)行run().[線程的任務(wù)寫在run()中]

public void run(){

for(int i=0;i<100;i++)

System.out.println("Thread1在運(yùn)行");

}

}

public class ThreadTest {

? public static void main(String[] args) {

Thread1 th = new Thread1(); //1.創(chuàng)建新線程對(duì)象

th.start(); //2.啟動(dòng)線程Thread1

for(int i=0;i<100;i++)

System.out.println("main在運(yùn)行");//4.執(zhí)行完線程后,執(zhí)行主線程中剩余的語(yǔ)句。

}

}


在這里有兩條執(zhí)行線索。由于線程的執(zhí)行速度取決于CPU時(shí)間及速度,因此線程的程序在不同的機(jī)器上運(yùn)行時(shí),線程交替占用CPU的情況可能不一樣。因此運(yùn)行結(jié)果也會(huì)出現(xiàn)一些差別。

2.通過(guò)實(shí)現(xiàn)Runnable接口創(chuàng)建線程

格式:

class Thread1 implements Runnable{

? ? ? ? ? public void run(){

? ? ? ? }

}

public class RunnableTest {

public static void main(String[] args) {

/*與繼承Thread類創(chuàng)建線程的區(qū)別,

就是把實(shí)現(xiàn)相關(guān)的創(chuàng)建的實(shí)例對(duì)象傳給了Thread,同時(shí)Thread又創(chuàng)建了對(duì)象。

*/

Thread2 th2 = new Thread2();

Thread t1 = new Thread(th2);

t1.start();

}

實(shí)例:

package Thread;

/*(1)通過(guò)Runnable接口創(chuàng)建線程,基本與繼承Thread類創(chuàng)建線程一致,就是在主類中有區(qū)別。

? *(2)與繼承Thread類創(chuàng)建線程的區(qū)別:

就是把實(shí)現(xiàn)相關(guān)的創(chuàng)建的實(shí)例對(duì)象傳給了Thread,同時(shí)Thread又創(chuàng)建了對(duì)象。

? *? ? 然后利用Thread的實(shí)例化對(duì)象啟動(dòng)線程。

? * */

class Thread2 implements Runnable{

public void run(){

for(int i=0;i<100;i++)

System.out.println("Thread1在運(yùn)行");

}

}

public class RunnableTest {

public static void main(String[] args) {

/*與繼承Thread類創(chuàng)建線程的區(qū)別,

就是把實(shí)現(xiàn)相關(guān)的創(chuàng)建的實(shí)例對(duì)象傳給了Thread,同時(shí)Thread又創(chuàng)建了對(duì)象。

*/

Thread2 th2 = new Thread2();

Thread t1 = new Thread(th2);

t1.start();

for(int i=0;i<100;i++)

System.out.println("main在運(yùn)行");

}

}

3.實(shí)例-龜兔賽跑

4.線程之間的數(shù)據(jù)交流

同一個(gè)進(jìn)程中的幾個(gè)線程之間是可以 共享數(shù)據(jù)的。

例如:在龜兔賽跑中,可以通過(guò)獎(jiǎng)勵(lì)他們食物的方式激勵(lì)他們賽跑。

而食物就是烏龜和兔子共享的數(shù)據(jù)。

則共享數(shù)據(jù)有兩種方式:

1.通過(guò)內(nèi)類創(chuàng)建線程

2.通過(guò)構(gòu)造器傳遞參數(shù)

1.通過(guò)內(nèi)類創(chuàng)建線程

內(nèi)類的作用是可以直接訪問(wèn)外類的成員變量。即把共享數(shù)據(jù)定義為外類的成員變量,烏龜和兔子定義為內(nèi)類,這樣就可以實(shí)現(xiàn)兩個(gè)線程之間的數(shù)據(jù)交流了。

在本例子中,inrabtort類是包含了主類,兔子類,烏龜類。其中主類外面定義了food,作為外類的成員變量。

實(shí)例:

//把所有類都寫在主類里了,且成員變量定義在主類外面。????

內(nèi)類:把一個(gè)類(內(nèi)類)定義在另一個(gè)類(外類)中。

inrabtort.java?

package thread;

public class inrabtort {

public int food = 10;

public static void main(String argps[]){

inrabtort tt = new inrabtort();

tt.go();

}

public void go(){

tortoise r1 = new tortoise();

rabbit r2 = new rabbit();

r1.start();

r2.start();

}

class tortoise extends Thread{

int i,f=0;

public void run(){

for(i=1;i<=10;i++){

System.out.println("烏龜跑到了"+i+"米處");

if(food>0){

food--;f++;

System.out.println("烏龜吃了第"+f+"個(gè)食物,還剩food="+food);

}

}

}

}

class rabbit extends Thread{

int i,f=0;

public void run(){

for(i=1;i<=10;i++){

System.out.println("兔子跑到了"+i+"米處");

if(food>0){

food--;f++;

System.out.println("兔子吃了第"+f+"個(gè)食物,還剩food="+food);

}

}

}

}

}

2.通過(guò)構(gòu)造器傳遞參數(shù)(比較好用,不出錯(cuò))

把共享數(shù)據(jù)寫在一個(gè)單獨(dú)的類里,然后通過(guò)構(gòu)造器傳遞參數(shù)給各個(gè)線程。也可以對(duì)公用數(shù)據(jù)定義方法,供各個(gè)線程使用。

在本例中,把food這個(gè)共享數(shù)據(jù)單獨(dú)放在一個(gè)類里,然后在兔子類和烏龜類里都定義了food fd;

然后并設(shè)置了構(gòu)造器進(jìn)行賦值,然后進(jìn)行了引用。也就是說(shuō)food類,烏龜類,兔子類,主類這四個(gè)是并列的。

實(shí)例:

package thread;

import thread.inrabtort.rabbit;

import thread.inrabtort.tortoise;

class food{

public int food =10; //共同訪問(wèn)的數(shù)據(jù)

}

public class structrabtort {

public static void main(String argps[]){

structrabtort? tt = new? structrabtort();

tt.go();

}

public void go(){

food f1 =new food();

tortoise1 r1 = new tortoise1(f1);

rabbit1 r2 = new rabbit1(f1);

r1.start();

r2.start();

}

}

class tortoise1 extends Thread{

int i;

int f=0;

food fd;

public tortoise1(food fd) {

this.fd = fd;

}

public void run(){

for(i=1;i<11;i++){

System.out.println("烏龜跑到了"+i+"米處");

if(fd.food>0){

fd.food--;f++;

System.out.println("烏龜吃了第"+f+"個(gè)食物,還剩food="+fd.food);

}

}

}

}

class rabbit1 extends Thread{

int i,f=0;

food fd;

public rabbit1(food fd) {

this.fd = fd;

}

public void run(){

for(i=1;i<11;i++){

System.out.println("兔子跑到了"+i+"米處");

if(fd.food>0){

fd.food--;f++;

System.out.println("兔子吃了第"+f+"個(gè)食物,還剩food="+fd.food);

}

}

}

}

5.線程調(diào)度

(1)為什么存在線程調(diào)度?



(2)優(yōu)先級(jí)

默認(rèn)優(yōu)先級(jí)是5,可以通過(guò)線程實(shí)例對(duì)象.setPriority(1-10之間的數(shù)字)進(jìn)行設(shè)置。

(3)sleep(),yield(),join()的介紹

? ?使用格式:Thread.sleep(1000);






7.線程同步(synchronized 標(biāo)記)

如果不會(huì),在eclipse里輸入syn+ alt +?進(jìn)行提示。

實(shí)現(xiàn)線程同步化需要使用synchronized 關(guān)鍵字。

保證任意時(shí)刻只有一個(gè)線程訪問(wèn)該共享數(shù)據(jù)。






8.線程死鎖





?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

推薦閱讀更多精彩內(nèi)容

  • 本文主要講了java中多線程的使用方法、線程同步、線程數(shù)據(jù)傳遞、線程狀態(tài)及相應(yīng)的一些線程函數(shù)用法、概述等。 首先講...
    李欣陽(yáng)閱讀 2,493評(píng)論 1 15
  • Java多線程學(xué)習(xí) [-] 一擴(kuò)展javalangThread類 二實(shí)現(xiàn)javalangRunnable接口 三T...
    影馳閱讀 2,987評(píng)論 1 18
  • 1. Java基礎(chǔ)部分 基礎(chǔ)部分的順序:基本語(yǔ)法,類相關(guān)的語(yǔ)法,內(nèi)部類的語(yǔ)法,繼承相關(guān)的語(yǔ)法,異常的語(yǔ)法,線程的語(yǔ)...
    子非魚_t_閱讀 31,765評(píng)論 18 399
  • “阿爸,阿媽、你們快過(guò)來(lái)看!” 烏力古拖著阿媽的手向前跑,阿媽含著笑任由他拉著,看著他像看一只小馬駒,阿爸在后面跟...
    流星尾閱讀 601評(píng)論 0 5
  • 假如這歲月可饒人 我愿用十年換你安康 音容笑貌 哪怕是吹過(guò)你的風(fēng) 都是那么快樂(lè) 假如你少女情懷悸動(dòng)時(shí) 做了另一番抉...
    魚夏生閱讀 290評(píng)論 2 3