給你一個(gè)經(jīng)典的例子。run里面放空循環(huán)來觀察多線程是不合理的,空循環(huán)消耗時(shí)序極小,用sleep來間隔時(shí)間才是合理的。

在資中等地區(qū),都構(gòu)建了全面的區(qū)域性戰(zhàn)略布局,加強(qiáng)發(fā)展的系統(tǒng)性、市場(chǎng)前瞻性、產(chǎn)品創(chuàng)新能力,以專注、極致的服務(wù)理念,為客戶提供網(wǎng)站制作、成都網(wǎng)站制作 網(wǎng)站設(shè)計(jì)制作按需求定制網(wǎng)站,公司網(wǎng)站建設(shè),企業(yè)網(wǎng)站建設(shè),成都品牌網(wǎng)站建設(shè),成都全網(wǎng)營(yíng)銷,外貿(mào)營(yíng)銷網(wǎng)站建設(shè),資中網(wǎng)站建設(shè)費(fèi)用合理。
class?RunnableDemo?implements?Runnable?{
private?Thread?t;
private?String?threadName;
RunnableDemo(?String?name)?{
threadName?=?name;
System.out.println("Creating?"?+??threadName?);
}
public?void?run()?{
System.out.println("Running?"?+??threadName?);
try?{
for(int?i?=?4;?i??0;?i--)?{
System.out.println("Thread:?"?+?threadName?+?",?"?+?i);
//?Let?the?thread?sleep?for?a?while.
Thread.sleep(50);
}
}catch?(InterruptedException?e)?{
System.out.println("Thread?"?+??threadName?+?"?interrupted.");
}
System.out.println("Thread?"?+??threadName?+?"?exiting.");
}
public?void?start?()?{
System.out.println("Starting?"?+??threadName?);
if?(t?==?null)?{
t?=?new?Thread?(this,?threadName);
t.start?();
}
}
}
public?class?TestThread?{
public?static?void?main(String?args[])?{
RunnableDemo?R1?=?new?RunnableDemo(?"Thread-1");
R1.start();
RunnableDemo?R2?=?new?RunnableDemo(?"Thread-2");
R2.start();
}???
}
可以同時(shí)運(yùn)行。另外,你的類名最好是大寫;想要使用線程類,最好是實(shí)現(xiàn)Runnable接口。
一、 什么是多線程:
我們現(xiàn)在所使用操作系統(tǒng)都是多任務(wù)操作系統(tǒng)(早期使用的DOS操作系統(tǒng)為單任務(wù)操作系統(tǒng)),多任務(wù)操作指在同一時(shí)刻可以同時(shí)做多件事(可以同時(shí)執(zhí)行多個(gè)程序)。
多進(jìn)程:每個(gè)程序都是一個(gè)進(jìn)程,在操作系統(tǒng)中可以同時(shí)執(zhí)行多個(gè)程序,多進(jìn)程的目的是為了有效的使用CPU資源,每開一個(gè)進(jìn)程系統(tǒng)要為該進(jìn)程分配相關(guān)的系統(tǒng)資源(內(nèi)存資源)
多線程:線程是進(jìn)程內(nèi)部比進(jìn)程更小的執(zhí)行單元(執(zhí)行流|程序片段),每個(gè)線程完成一個(gè)任務(wù),每個(gè)進(jìn)程內(nèi)部包含了多個(gè)線程每個(gè)線程做自己的事情,在進(jìn)程中的所有線程共享該進(jìn)程的資源;
主線程:在進(jìn)程中至少存在一個(gè)主線程,其他子線程都由主線程開啟,主線程不一定在其他線程結(jié)束后結(jié)束,有可能在其他線程結(jié)束前結(jié)束。Java中的主線程是main線程,是Java的main函數(shù);
二、 Java中實(shí)現(xiàn)多線程的方式:
繼承Thread類來實(shí)現(xiàn)多線程:
當(dāng)我們自定義的類繼承Thread類后,該類就為一個(gè)線程類,該類為一個(gè)獨(dú)立的執(zhí)行單元,線程代碼必須編寫在run()方法中,run方法是由Thread類定義,我們自己寫的線程類必須重寫run方法。
run方法中定義的代碼為線程代碼,但run方法不能直接調(diào)用,如果直接調(diào)用并沒有開啟新的線程而是將run方法交給調(diào)用的線程執(zhí)行
要開啟新的線程需要調(diào)用Thread類的start()方法,該方法自動(dòng)開啟一個(gè)新的線程并自動(dòng)執(zhí)行run方法中的內(nèi)容
請(qǐng)點(diǎn)擊輸入圖片描述
結(jié)果:
請(qǐng)點(diǎn)擊輸入圖片描述
java多線程的啟動(dòng)順序不一定是線程執(zhí)行的順序,各個(gè)線程之間是搶占CPU資源執(zhí)行的,所有有可能出現(xiàn)與啟動(dòng)順序不一致的情況。
CPU的調(diào)用策略:
如何使用CPU資源是由操作系統(tǒng)來決定的,但操作系統(tǒng)只能決定CPU的使用策略不能控制實(shí)際獲得CPU執(zhí)行權(quán)的程序。
線程執(zhí)行有兩種方式:
1.搶占式:
目前PC機(jī)中使用最多的一種方式,線程搶占CPU的執(zhí)行權(quán),當(dāng)一個(gè)線程搶到CPU的資源后并不是一直執(zhí)行到此線程執(zhí)行結(jié)束,而是執(zhí)行一個(gè)時(shí)間片后讓出CPU資源,此時(shí)同其他線程再次搶占CPU資源獲得執(zhí)行權(quán)。
2.輪循式;
每個(gè)線程執(zhí)行固定的時(shí)間片后讓出CPU資源,以此循環(huán)執(zhí)行每個(gè)線程執(zhí)行相同的時(shí)間片后讓出CPU資源交給下一個(gè)線程執(zhí)行。
希望對(duì)您有所幫助!~
我用的是方法鎖,這是用Android?Studio測(cè)試類寫的,自己寫個(gè)Main函數(shù),復(fù)制里面的方法,然后調(diào)用
/**
*?Created?by?Svnt?on?2016-09-26.
*/
public?class?MyApplication?extends?ApplicationTest{
public?void?testThread(){
MyRunnable?myRunnable?=?new?MyRunnable();
//線程并發(fā)
new?Thread(myRunnable,"A").start();
new?Thread(myRunnable,"B").start();
new?Thread(myRunnable,"C").start();
}
}
/**
*?存錢的(Runnable)線程
*/
class?MyRunnable?implements?Runnable?{
double?mMoney;
@Override
public?synchronized?void?run()?{
for?(int?i?=?0?;?i??3;?i++){
mMoney?+=?1000;
Log.e("-main-",Thread.currentThread().getName()+"余額剩余?=?"+mMoney);
}
}
}
首先,你同步的是具體的某個(gè)Test實(shí)例, 對(duì)于那個(gè)實(shí)例來說,實(shí)際上只有一個(gè)線程訪問了那個(gè)代碼塊,但是sum和other卻是多個(gè)線程同時(shí)去進(jìn)行訪問,實(shí)際上這是不安全的,如果你想實(shí)現(xiàn)每次都輸出10000的效果,那么正確的應(yīng)該是在Test.class上加鎖,而不是獲取Test實(shí)例的鎖,修改后的代碼如下:
public?class?Test?extends?Thread?{
public?static?int?sum?=?10000;
public?static?int?other?=?0;
public?void?getMoney()?{
synchronized?(Test.class)?{
System.out.println(Thread.currentThread().getName()?+?"?開始執(zhí)行");
sum?=?sum?-?100;
System.out.println("sum-100");
other?=?other?+?100;
System.out.println("other+100");
System.out.println(sum?+?other);
System.out.println(Thread.currentThread().getName()?+?"?執(zhí)行完成");
}
}
public?void?run()?{
getMoney();
}
public?static?void?main(String[]?agrs)?{
Thread?t[]?=?new?Thread[10];
for?(int?i?=?0;?i?=?9;?i++)?{
t[i]?=?new?Test();
t[i].start();
}
}
}
// 上面代碼能得到你的結(jié)果
Java 給多線程編程提供了內(nèi)置的支持。 一條線程指的是進(jìn)程中一個(gè)單一順序的控制流,一個(gè)進(jìn)程中可以并發(fā)多個(gè)線程,每條線程并行執(zhí)行不同的任務(wù)。
新建狀態(tài):
使用 new 關(guān)鍵字和 Thread 類或其子類建立一個(gè)線程對(duì)象后,該線程對(duì)象就處于新建狀態(tài)。它保持這個(gè)狀態(tài)直到程序 start() 這個(gè)線程。
就緒狀態(tài):
當(dāng)線程對(duì)象調(diào)用了start()方法之后,該線程就進(jìn)入就緒狀態(tài)。就緒狀態(tài)的線程處于就緒隊(duì)列中,要等待JVM里線程調(diào)度器的調(diào)度。
運(yùn)行狀態(tài):
如果就緒狀態(tài)的線程獲取 CPU 資源,就可以執(zhí)行 run(),此時(shí)線程便處于運(yùn)行狀態(tài)。處于運(yùn)行狀態(tài)的線程最為復(fù)雜,它可以變?yōu)樽枞麪顟B(tài)、就緒狀態(tài)和死亡狀態(tài)。
阻塞狀態(tài):
如果一個(gè)線程執(zhí)行了sleep(睡眠)、suspend(掛起)等方法,失去所占用資源之后,該線程就從運(yùn)行狀態(tài)進(jìn)入阻塞狀態(tài)。在睡眠時(shí)間已到或獲得設(shè)備資源后可以重新進(jìn)入就緒狀態(tài)。可以分為三種:
等待阻塞:運(yùn)行狀態(tài)中的線程執(zhí)行 wait() 方法,使線程進(jìn)入到等待阻塞狀態(tài)。
同步阻塞:線程在獲取 synchronized 同步鎖失敗(因?yàn)橥芥i被其他線程占用)。
其他阻塞:通過調(diào)用線程的 sleep() 或 join() 發(fā)出了 I/O 請(qǐng)求時(shí),線程就會(huì)進(jìn)入到阻塞狀態(tài)。當(dāng)sleep() 狀態(tài)超時(shí),join() 等待線程終止或超時(shí),或者 I/O 處理完畢,線程重新轉(zhuǎn)入就緒狀態(tài)。
死亡狀態(tài):
一個(gè)運(yùn)行狀態(tài)的線程完成任務(wù)或者其他終止條件發(fā)生時(shí),該線程就切換到終止?fàn)顟B(tài)。
本文標(biāo)題:java多線程編程代碼 java多線程網(wǎng)絡(luò)編程
本文鏈接:http://chinadenli.net/article16/doojpgg.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供App開發(fā)、服務(wù)器托管、虛擬主機(jī)、微信小程序、定制網(wǎng)站、網(wǎng)站建設(shè)
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來源: 創(chuàng)新互聯(lián)