欧美性猛交XXXX免费看蜜桃,成人网18免费韩国,亚洲国产成人精品区综合,欧美日韩一区二区三区高清不卡,亚洲综合一区二区精品久久

打開(kāi)APP
userphoto
未登錄

開(kāi)通VIP,暢享免費電子書(shū)等14項超值服

開(kāi)通VIP
java學(xué)習日記_線(xiàn)程

一、線(xiàn)程的概念:
線(xiàn)程與進(jìn)程相似,是一段完成某個(gè)特定功能的代碼,是程序中單個(gè)順序的流控制;但與進(jìn)程不同的是,同類(lèi)的多個(gè)線(xiàn)程是共享一塊內存空間和一組系統資源,而線(xiàn)程本身的數據通常只有微處理器的寄存器數據,以及一個(gè)供程序執行時(shí)使用的堆棧。所以系統在產(chǎn)生一個(gè)線(xiàn)程,或者在各個(gè)線(xiàn)程之間切換時(shí),負擔要比進(jìn)程小的多,正因如此,線(xiàn)程被稱(chēng)為輕負荷進(jìn)程(light-weight process)。一個(gè)進(jìn)程中可以包含多個(gè)線(xiàn)程。

一個(gè)線(xiàn)程是一個(gè)程序內部的順序控制流。
  1. 進(jìn)程:每個(gè)進(jìn)程都有獨立的代碼和數據空間(進(jìn)程上下文) ,進(jìn)程切換的開(kāi)銷(xiāo)大。
  2. 線(xiàn)程:輕量的進(jìn)程,同一類(lèi)線(xiàn)程共享代碼和數據空間,每個(gè)線(xiàn)程有獨立的運行棧和程序計數器(pc),線(xiàn)程切換的開(kāi)銷(xiāo)小。
  3. 多進(jìn)程:在操作系統中,能同時(shí)運行多個(gè)任務(wù)程序。
  4. 多線(xiàn)程:在同一應用程序中,有多個(gè)順序流同時(shí)執行。

java內在支持多線(xiàn)程,它的所有類(lèi)都是在多線(xiàn)程下定義的,java利用多線(xiàn)程使整個(gè)系統成為異步系統。
  1. 虛擬的cpu,封裝在java.lang.thread類(lèi)中。
  2. cpu所執行的代碼,傳遞給thread類(lèi)。
  3. cpu所處理的數據,傳遞給thread類(lèi)。

二、線(xiàn)程的構造
線(xiàn)程實(shí)例表示java解釋器中的真正的線(xiàn)程,通過(guò)它可以啟動(dòng)線(xiàn)程、終止線(xiàn)程、線(xiàn)程掛起等,每個(gè)線(xiàn)程都是通過(guò)類(lèi)thread在java的軟件包java.lang中定義,它的構造方法為:

   public thread (threadgroup group,runnable target,string name);

  其中,group 指明該線(xiàn)程所屬的線(xiàn)程組;target實(shí)際執行線(xiàn)程體的目標對象,它必須實(shí)現接口runnable; name為線(xiàn)程名。java中的每個(gè)線(xiàn)程都有自己的名稱(chēng),java提供了不同thread類(lèi)構造器,允許給線(xiàn)程指定名稱(chēng)。如果name為null時(shí),則java自動(dòng)提供唯一的名稱(chēng)。
當上述構造方法的某個(gè)參數為null時(shí),我們可得到下面的幾個(gè)構造方法:

  public thread ();
  public thread (runnable target);
  public thread (runnable target,string name);
  public thread (string name);
  public thread (threadgroup group,runnable target);
  public thread (threadgroup group,string name);

  一個(gè)類(lèi)聲明實(shí)現runnable接口就可以充當線(xiàn)程體,在接口runnable中只定義了一個(gè)方法 run():
       public void run();

  任何實(shí)現接口runnable的對象都可以作為一個(gè)線(xiàn)程的目標對象,類(lèi)thread本身也實(shí)現了接口runnable,因此我們可以通過(guò)兩種方法實(shí)現線(xiàn)程體。

 ?。ㄒ唬┒x一個(gè)線(xiàn)程類(lèi),它繼承線(xiàn)程類(lèi)thread并重寫(xiě)其中的方法 run(),這時(shí)在初始化這個(gè)類(lèi)的實(shí)例時(shí),目標target可為null,表示由這個(gè)實(shí)例對來(lái)執行線(xiàn)程體。由于java只支持單重繼承,用這種方法定義的類(lèi)不能再繼承其它父類(lèi)。

 ?。ǘ┨峁┮粋€(gè)實(shí)現接口runnable的類(lèi)作為一個(gè)線(xiàn)程的目標對象,在初始化一個(gè)thread類(lèi)或者thread子類(lèi)的線(xiàn)程對象時(shí),把目標對象傳遞給這個(gè)線(xiàn)程實(shí)例,由該目標對象提供線(xiàn)程體 run()。這時(shí),實(shí)現接口runnable的類(lèi)仍然可以繼承其它父類(lèi)。



三、線(xiàn)程的狀態(tài)
  每個(gè)線(xiàn)程都是通過(guò)某個(gè)特定thread對象的方法run( )來(lái)完成其操作的,方法run( )稱(chēng)為線(xiàn)程體。下圖表示了java線(xiàn)程的不同狀態(tài)以及狀態(tài)之間轉換所調用的方法。

1. 創(chuàng )建狀態(tài)(new thread)
  執行下列語(yǔ)句時(shí),線(xiàn)程就處于創(chuàng )建狀態(tài):
  thread mythread = new thread( );
  當一個(gè)線(xiàn)程處于創(chuàng )建狀態(tài)時(shí),它僅僅是一個(gè)空的線(xiàn)程對象,系統不為它分配資源。

  2. 可運行狀態(tài)( runnable )
  thread mythread = new thread( );
  mythread.start( );
  當一個(gè)線(xiàn)程處于可運行狀態(tài)時(shí),系統為這個(gè)線(xiàn)程分配了它需的系統資源,安排其運行并調用線(xiàn)程運行方法,這樣就使得該線(xiàn)程處于可運行( runnable )狀態(tài)。需要注意的是這一狀態(tài)并不是運行中狀態(tài)(running ),因為線(xiàn)程也許實(shí)際上并未真正運行。由于很多計算機都是單處理器的,所以要在同一時(shí)刻運行所有的處于可運行狀態(tài)的線(xiàn)程是不可能的,java的運行系統必須實(shí)現調度來(lái)保證這些線(xiàn)程共享處理器。
  
  3. 不可運行狀態(tài)(not runnable)
  進(jìn)入不可運行狀態(tài)的原因有如下幾條:
  1) 調用了sleep()方法;
  2) 調用了suspend()方法;
  3) 為等候一個(gè)條件變量,線(xiàn)程調用wait()方法;
  4) 輸入輸出流中發(fā)生線(xiàn)程阻塞;
  不可運行狀態(tài)也稱(chēng)為阻塞狀態(tài)(blocked)。因為某種原因(輸入/輸出、等待消息或其它阻塞情況),系統不能執行線(xiàn)程的狀態(tài)。這時(shí)即使處理器空閑,也不能執行該線(xiàn)程。

  4. 死亡狀態(tài)(dead)
  線(xiàn)程的終止一般可通過(guò)兩種方法實(shí)現:自然撤消(線(xiàn)程執行完)或是被停止(調用stop()方法)。目前不推薦通過(guò)調用stop()來(lái)終止線(xiàn)程的執行,而是讓線(xiàn)程執行完。


四、有關(guān)線(xiàn)程的一些長(cháng)用的方法
1. sleep(long millis)
這個(gè)方法是一個(gè)靜態(tài)的方法,也就是說(shuō)我們可以直接調用它,如thread.sleep(5000)就是指讓目前正在運行的線(xiàn)程先停下工作等待5000毫秒。有一點(diǎn)需要注意的是:不能肯定這個(gè)線(xiàn)程在過(guò)5000毫秒肯定會(huì )立刻被執行。

2.interrupt()
這個(gè)方法用來(lái)打斷一個(gè)線(xiàn)程(感覺(jué)說(shuō)睡眠中的進(jìn)程更加合適)。這個(gè)方法的作用可以舉個(gè)例子來(lái)看一下:
public class testinterrupt extends thread
{

/** creates a new instance of testinterrupt */
public testinterrupt()
{
}

public void run()
{
try
{

for ( int i=0; i<5; i++)
{
system.out.println("running the first loop " + i);
}
thread.sleep(10000);

for ( int i=6; i<10; i++)
{
system.out.println("running the second loop" + i);
}

}catch (interruptedexception ie)
{
system.out.println("sleep interrupted in run()");
for ( int i=11; i<15; i++)
{
system.out.println("running the third loop" + i);
}

}

}

public static void main(string[] args)
{
testinterrupt ti = new testinterrupt();
thread t = new thread(ti);
t.start();

//delay for a few seconds to let the other thread get going
try
{
thread.sleep(2500);
}catch (interruptedexception ie)
{
system.out.println("sleep interrupted in main()");
}

system.out.println("about to wake up the other thread");
t.interrupt();
system.out.println("exiting from main");

}
}

上面的例子中假如沒(méi)有t.interropt()的話(huà),程序運行做的就是
for ( int i=6; i<10; i++)
{
system.out.println("running the second loop" + i);
}
加上以后做的就是catch中的內容了.

3.join()和join(long millis)
join()這個(gè)函數的作用是使得目前正在運行的線(xiàn)程假如為a停下來(lái),一直到調用join()方法的這個(gè)線(xiàn)程b被執行完畢,再繼續一開(kāi)始的線(xiàn)程a;
看個(gè)例子好了:
public class testjoin1 extends thread
{

/** creates a new instance of testjoin1 */
public testjoin1()
{
}

public void run()
{
try
{

for ( int i=0; i<5; i++)
{
system.out.println("running the first loop " + i);
}
thread.sleep(1000);

for ( int i=6; i<10; i++)
{
system.out.println("running the second loop" + i);
}

}catch (interruptedexception ie)
{
system.out.println("sleep interrupted in run()");
}

}

public static void main(string[] args)
{
try
{
testjoin1 ti = new testjoin1();
thread t = new thread(ti);
t.start();
t.join();

for ( int i=11; i<15; i++)
{
system.out.println("running the third loop" + i);
}
}catch (interruptedexception ie)
{
system.out.println("join interrupted in run()");
}

system.out.println("exiting from main");

}
}
這個(gè)程序的結果是先讓t.join()時(shí)刻正在運行的線(xiàn)程(其實(shí)就是main)被擱置,做完了t這個(gè)線(xiàn)程的所有內容,再回到main線(xiàn)程繼續做的t.join();語(yǔ)句后剩下的內容.假如把t.join()這行去掉的話(huà),在一般的計算機上跑出來(lái)的結果應該是先做了main所有的內容再去做t線(xiàn)程的內容.

join(long millis)這個(gè)方法和join()方法差不多,都是正在執行的線(xiàn)程a被擱置,去做調用join(long millis)這個(gè)方法的線(xiàn)程b的run里面的內容。但后面的millis這個(gè)參數決定了b這個(gè)線(xiàn)程能被優(yōu)先運行多少時(shí)間(millis代表多少毫秒),millis豪秒過(guò)后b線(xiàn)程即使沒(méi)有運行完畢,也會(huì )回到線(xiàn)程a.
底下的一個(gè)程序能很好的說(shuō)明這個(gè)問(wèn)題:
public class testjoin2 extends thread
{

/** creates a new instance of testjoin2 */
public testjoin2()
{
}

public void run()
{
try
{

for ( int i=0; i<5; i++)
{
system.out.println("running the first loop " + i);
}
thread.sleep(3500);

for ( int i=6; i<10; i++)
{
system.out.println("running the second loop" + i);
}

}catch (interruptedexception ie)
{
system.out.println("sleep interrupted in run()");
}

}

public static void main(string[] args)
{
try
{
testjoin2 t2 = new testjoin2();
thread t = new thread(t2);
t.start();
t.join(3000);

for ( int i=11; i<15; i++)
{
system.out.println("running the third loop" + i);
}
}catch (interruptedexception ie)
{
system.out.println("join interrupted in run()");
}
system.out.println("exiting from main");

}
}

看了這么多以后,好象很容易產(chǎn)生一種誤解join()這個(gè)函數就是讓調用這個(gè)方法的線(xiàn)程b優(yōu)先(第一個(gè))被執行.其實(shí)事實(shí)并不是這樣的,join()的作用如上面所說(shuō)的,它只能讓目前運行的線(xiàn)程a擱置等,等b執行完畢再開(kāi)始執行a.
底下的程序可以讓人消除這中誤解:
public class test extends thread
{
public test(string a)
{
super(a);
}


public void run()
{
system.out.println(this.getname());
}

public static void main(string [] args)
{
test a = new test("a");
test b = new test("b");
test c = new test("c");

a.start();
b.start();
c.start();
try
{
c.join();
}
catch(exception e){
}
system.out.println("this is main!");
}
}

看了運行結果是a,b先被執行了,然后才是c,最后是main^^;

4.關(guān)于synchronized
這個(gè)關(guān)鍵字出現的目的是為了讓幾個(gè)線(xiàn)程能同步,舉一個(gè)最簡(jiǎn)單的例子。一個(gè)電影院有20張票要賣(mài),它有3個(gè)售票員。
寫(xiě)個(gè)程序來(lái)證實(shí)一下不用synchronized的結果好了,需要使用sleep()函數來(lái)制造出這種可能(線(xiàn)程的執行時(shí)機誰(shuí)也不能預料)出現的情況:
public class sell
{
public static void main(string [] args)
{
sellthread sell = new sellthread();
thread sell1 = new thread(sell,"sellman1");
thread sell2 = new thread(sell,"sellman2");
thread sell3 = new thread(sell,"sellman3");
sell1.start();
sell2.start();
sell3.start();
}
}

class sellthread implements runnable
{
private int i = 20;
public void run()
{
while(true)
{
if( i > 0)
{
try
{
thread.sleep(100);
} catch(exception e)
{
}

system.out.println(thread.currentthread().getname() + " sell " + i--);
}
}
}
}

結果一共賣(mài)掉了22張票(估計電影院以為無(wú)緣無(wú)故多收了門(mén)票錢(qián)會(huì )很高興,不過(guò)一會(huì )也許就要面對憤怒的顧客了....)
這個(gè)時(shí)候我們的synchronized應該發(fā)揮作用了^^修改程序如下:
public class sell2
{
public static void main(string [] args)
{
sellthread sell = new sellthread();
thread sell1 = new thread(sell,"sellman1");
thread sell2 = new thread(sell,"sellman2");
thread sell3 = new thread(sell,"sellman3");
sell1.start();
sell2.start();
sell3.start();
}
}

class sellthread implements runnable
{
private int i = 20;
string a = "now ok!";
public void run()
{
while(true)
{
synchronized(a)
{
if( i > 0)
{
try
{
thread.sleep(100);
} catch(exception e)
{
}

system.out.println(thread.currentthread().getname() + " sell " + i--);
}
}
}
}
}

這樣就好了只會(huì )賣(mài)20張票了, synchronized()中的括號中需要的是一個(gè)class的對象所以我們不能直接在括號中寫(xiě)上i,就定義了一個(gè)string的對象a,a的標志旗(不知道說(shuō)什么更合適)本來(lái)為1代表大家都能使用,這樣一個(gè)售票員selln的賣(mài)票線(xiàn)程拿到了a以后他就可以開(kāi)始賣(mài)票,同時(shí)他把a這個(gè)對象標志旗置為0,然后其他售票員賣(mài)票的線(xiàn)程發(fā)現他們拿不到a這個(gè)對象了就只先擱置了.一直到selln的賣(mài)票線(xiàn)程釋放了a,a的標志旗就又變成了1,這個(gè)時(shí)候其他售票員的賣(mài)票的線(xiàn)程就可以競爭了,看誰(shuí)先拿到a這個(gè)對象.不過(guò)string a和賣(mài)票沒(méi)什么關(guān)系,所以我們可以用this來(lái)代替synchronized()中的a,它和a的效果一樣表示誰(shuí)拿到了this對象才能執行.


這里有兩個(gè)容易誤解的地方:
(1).一個(gè)線(xiàn)程拿到synchronized的括號中的對象之后,其他也要需要拿到這個(gè)對象才能運行的線(xiàn)程不能被執行了.其實(shí)是其他線(xiàn)程也是可以執行的,但他們執行到了需要synchronized中對象的時(shí)候,他們發(fā)現對象的標志旗為0,所以只能又被擱置了。(看來(lái)幸運女神只能同時(shí)光顧一個(gè)人^^)所以我們用synchronized來(lái)使得線(xiàn)程同步的時(shí)候是以犧牲效率為代價(jià)的,所以不需要使用的地方就別用好了.

(2),一個(gè)線(xiàn)程拿到synchronized的括號中的對象之后,其他任何線(xiàn)程都不能執行了,其實(shí)假如其他不需要synchronized的對象才能繼續執行的線(xiàn)程還是可以和拿到synchronized的括號中的對象的線(xiàn)程一起運行的。

有的方法前面被加上了synchronized.其實(shí)這個(gè)時(shí)候就是把這個(gè)方法的調用者,也就是this的標志旗置0了,他不能和其他需要this才能運行的線(xiàn)程一起執行,但可以和其他不需要這個(gè)this對象的線(xiàn)程一起運行。

5.wait()和notify()或者notifyall()
這個(gè)幾個(gè)函數是為了使得幾個(gè)同步的線(xiàn)程按照一定的先后順序執行。
都是和synchronized()一起使用,設()中對象為obj吧。
有一點(diǎn)需要注意的是,我們應該讓需要obj.wait的線(xiàn)程先啟動(dòng)。因為執行順序是需要obj.wait()的線(xiàn)程a先啟動(dòng),然后它運行到obj.wait()的時(shí)候,進(jìn)入擱置狀態(tài),讓其他線(xiàn)程先執行。于是帶用obj.notify()的線(xiàn)程b開(kāi)始執行了,一直到b執行到了obj.notify()以后(obj.notify()實(shí)際上就是通知因為obj.wait()被擱置的線(xiàn)程:"輪到你了"),b被擱置,然后繼續做a的obj.wait()以后的內容.
所以我們假如讓帶有obj.notify()的線(xiàn)程b先運行的話(huà),那么b執行完畢以后,b執行的obj.notify()沒(méi)有找到任何在因obj.wait()而進(jìn)入擱置狀態(tài)的線(xiàn)程.然后開(kāi)始做帶有obj.wait()的線(xiàn)程a的話(huà).a運行到了obj.wait()就進(jìn)入擱置狀態(tài),等待另外一個(gè)線(xiàn)程中的obj.notify()來(lái)喚醒它,不過(guò)可惜它永遠也等不到了,因為帶有obj.notify()的線(xiàn)程已經(jīng)到擱置的線(xiàn)程中來(lái)找過(guò)它一次,很可惜的是沒(méi)找到.于是線(xiàn)程a就一直擱置了...(感覺(jué)有點(diǎn)像愛(ài)情劇...);
舉個(gè)例子好了:
public class threadtest
{
public static void main(string [] args)
{
storage stor = new storage();
counter a = new counter(stor);
printer b = new printer(stor);


a.start();
b.start();
}
}

class storage
{
public int i = 0;
}

class counter extends thread
{
private storage a;
public counter(storage stor)
{
a = stor;
}

public void run()
{
system.out.println("hi");
try
{
sleep(100);
}
catch(exception e) {}
int i = 0;
while(i < 5)
{
synchronized(a)
{
system.out.println("counter");
a.i = (int)(math.random()*50);
system.out.println(a.i);
a.notify();
}
system.out.println("counter2");
++i;
}

}
}

class printer extends thread
{
private storage a;
public printer(storage stor)
{
a = stor;
}

public void run()
{
int i = 0;
while(i < 5)
{
synchronized(a)
{
system.out.println("printer");
try{
a.wait();
}
catch(interruptedexception e) {}
system.out.println(a.i);
}
system.out.println("printer2");
++i;
}
}
}

運行好了以后把
try
{
sleep(100);
}
catch(exception e) {}
這幾行注釋掉再看看運行結果吧。

還有兩點(diǎn)說(shuō)下:
(1).假如幾個(gè)線(xiàn)程因為obj.wait()進(jìn)入擱置的話(huà),那么只要一個(gè)obj.notifyall()執行以后,他們都處于可以運行狀態(tài),不過(guò)到底誰(shuí)先運行我們不就知道。

(2).sleep()和wait()有時(shí)候可以執行相同的功能不過(guò)要注意的是thread.sleep(long a)過(guò)了a毫秒以后,表示可以開(kāi)始執行了,不代表thread立刻被執行。thread.wait()一但接受到了thread.notify()以后是立刻被執行的.



本站僅提供存儲服務(wù),所有內容均由用戶(hù)發(fā)布,如發(fā)現有害或侵權內容,請點(diǎn)擊舉報。
打開(kāi)APP,閱讀全文并永久保存 查看更多類(lèi)似文章
猜你喜歡
類(lèi)似文章
第十一講:多線(xiàn)程與多線(xiàn)程
08語(yǔ)法總結 - 線(xiàn)程
多線(xiàn)程編程
[高并發(fā)]Java高并發(fā)編程系列開(kāi)山篇
Java線(xiàn)程及多線(xiàn)程技術(shù)及應用
java并發(fā)(四)如何創(chuàng )建并運行java線(xiàn)程
更多類(lèi)似文章 >>
生活服務(wù)
分享 收藏 導長(cháng)圖 關(guān)注 下載文章
綁定賬號成功
后續可登錄賬號暢享VIP特權!
如果VIP功能使用有故障,
可點(diǎn)擊這里聯(lián)系客服!

聯(lián)系客服

欧美性猛交XXXX免费看蜜桃,成人网18免费韩国,亚洲国产成人精品区综合,欧美日韩一区二区三区高清不卡,亚洲综合一区二区精品久久