成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

多線程

Scholer / 1301人閱讀

摘要:線程啟動后系統(tǒng)就自動調(diào)用方法。守護(hù)線程的使用必須在之前設(shè)置,否則會跑出一個(gè)異常。你不能把正在運(yùn)行的常規(guī)線程設(shè)置為守護(hù)線程。在線程中產(chǎn)生的新線程也是的。線程的同步控制使用方法可以釋放對象鎖,使用或可以讓等待的一個(gè)或所有線程進(jìn)入就緒狀態(tài)。

線程的創(chuàng)建 線程:程序中單個(gè)順序的流控制稱為線程

一個(gè)進(jìn)程中可以含有多個(gè)線程

在操作系統(tǒng)中可以查看線程數(shù)

如:在Windows中,在任務(wù)管理器,右鍵,選擇列,選中“線程數(shù)”

一個(gè)進(jìn)程中的多個(gè)線程

分享CPU(并發(fā)的或以時(shí)間片的方式)
圖示如下:

共享內(nèi)存(如多個(gè)線程訪問同一對象)

Java從語言級別支持多線程
如:
Object中wait(), notify(),java.lang中的類 Thread

線程體---- run()方法來實(shí)現(xiàn)的。

線程啟動后,系統(tǒng)就自動調(diào)用run()方法。參考相關(guān)書:


所以我們自己調(diào)用run是不會產(chǎn)生新的線程的。

通常,run()方法執(zhí)行一個(gè)時(shí)間較長的操作

如一個(gè)循環(huán)

顯示一系列圖片

下載一個(gè)文件

創(chuàng)建線程 1. 通過繼承Thread類創(chuàng)建線程可以實(shí)現(xiàn)新線程:
class MyThread extends Thread {
    public void run() {
        for(int i=0;i<100;i++) {
            System.out.print (" " + i);
            public void run() { ...}
        }
//生成新線程
Thread thread = new Thread(mytask); thread.start();
    }
}

然而,并不推薦上述方式。參閱了《Introduction to Java Programming》:

This approach is, however, not recommended because it mixes the task and the mechanism of running the task. Separating the task from the thread is a preferred design.

因?yàn)門hread中還有其他的方法,這樣可能會混淆了Thread中固有的機(jī)制。
Thread類的方法很多,如下:

所以,更好的方式是重新定義一個(gè)類來實(shí)現(xiàn)抽象類Runnable類,然后采用基于接口的對象注入的方式新建一個(gè)Thread的對象。如第二個(gè)方法。

2. 通過向Thread()構(gòu)造方法傳遞Runnable對象來創(chuàng)建線程
class MyTask implements Runnable {
    public void run() { ...}
    }
//生成新線程
Thread thread = new Thread(mytask); thread.start();
}

圖示如下:

2.1 匿名類及Lambda表達(dá)式

使用示例:

public class TestThread4Anonymous {
    public static void main(String args[]) {
        //匿名類
        new Thread(){
            public void run() {
                for(int i=0; i<10; i++)    
                    System.out.println(i);
            }
        }.start();
        //Lambda表達(dá)式
        new Thread( ( ) -> { 
            for(int i=0; i<10; i++) 
                System.out.println(" "+ i); 
        } ).start();
    }
}
線程的控制 對線程的基本控制

線程的啟動:thread.start()

線程的結(jié)束:常用的方法是設(shè)定一個(gè)標(biāo)記變量,結(jié)束相應(yīng)的循環(huán)及方法。

暫時(shí)阻止線程的執(zhí)行,比如在線程中用暫停方法:thread.sleep( 1000 );

線程的優(yōu)先級

調(diào)用設(shè)定線程的優(yōu)先級setPriority( int priority)方法,默認(rèn)有以下三種
MIN_PRIORITY,MAX_PRIORITY,NORM_PRIORITY

后臺線程

線程有兩種:

一類是普通線程(非Daemon線程)
在Java程序中,若還有非Demon線程,則整個(gè)程序就不會結(jié)束

一類是Daemon線程(守護(hù)線程,后臺線程)
使用setDaemon(true);如果普通線程結(jié)束了,則后臺線程自動終止。

注:垃圾回收線程是后臺線程

代碼
public class daemon {
    public static void main(String args[]) {
        //創(chuàng)建子線程
        Runnable t = new MyThread2();
        Thread thread = new Thread(t);
        thread.setDaemon(true);
        thread.start();

        System.out.println( "主線程開始運(yùn)行." );
        try{
            Thread.sleep(500);
        }
        catch(InterruptedException ex){}
        System.out.println("主線程結(jié)束,子線程由于設(shè)置為守護(hù)線程,所以也應(yīng)該提前結(jié)束.");
    }
}

class MyThread2 implements Runnable {
    public void run() {
        for(int i=0; i<10; i++ ){
            System.out.println(  "子線程應(yīng)該循環(huán)10次,當(dāng)前的第"+i+"次");
            try{ Thread.sleep(100); }
            catch(InterruptedException ex){}
        }
    }
}

輸出結(jié)果:

主線程開始運(yùn)行.
子線程應(yīng)該循環(huán)10次,當(dāng)前的第0次
子線程應(yīng)該循環(huán)10次,當(dāng)前的第1次
子線程應(yīng)該循環(huán)10次,當(dāng)前的第2次
子線程應(yīng)該循環(huán)10次,當(dāng)前的第3次
子線程應(yīng)該循環(huán)10次,當(dāng)前的第4次
主線程結(jié)束,子線程由于設(shè)置為守護(hù)線程,所以也應(yīng)該提前結(jié)束.

可以從上面看出,守護(hù)線程即使在運(yùn)行中,也應(yīng)該隨著主線程的結(jié)束而提前結(jié)束。

守護(hù)線程的使用:

thread.setDaemon(true)必須在thread.start()之前設(shè)置,否則會跑出一個(gè)IllegalThreadStateException異常。你不能把正在運(yùn)行的常規(guī)線程設(shè)置為守護(hù)線程。

在Daemon線程中產(chǎn)生的新線程也是Daemon的。

守護(hù)線程應(yīng)該永遠(yuǎn)不去訪問固有資源,如文件、數(shù)據(jù)庫,因?yàn)樗鼤谌魏螘r(shí)候甚至在一個(gè)操作的中間發(fā)生中斷。

線程的同步

為什么線程需要同步:
同時(shí)運(yùn)行的線程需要共享數(shù)據(jù)、就必須考慮其它線程的狀態(tài)與行為,這時(shí)就需要實(shí)現(xiàn)同步。

Java實(shí)現(xiàn)流程:

Java引入了對象互斥鎖的概念,來保證共享數(shù)據(jù)操作的完整性。
每個(gè)對象都對應(yīng)于一個(gè)monitor(監(jiān)視器),它上面 一個(gè)稱為“互斥鎖(lock, mutex)”的標(biāo)記,這個(gè)標(biāo)記用來保證在任一時(shí)刻,只能有一個(gè)線程訪問該對象。
關(guān)鍵字synchronized用來與對象的互斥鎖聯(lián)系。

synchronized的用法(2種)

對代碼片斷:

synchronized(對象){ 。。。。}

對某個(gè)方法:

synchronized放在方法聲明中,如
public synchronized void push(char c ){ 。。。。}

以上相當(dāng)于對synchronized(this), 表示整個(gè)方法為同步方法。

線程的同步控制

使用wait()方法可以釋放對象鎖,使用notify()notifyAll()可以讓等待的一個(gè)或所有線程進(jìn)入就緒狀態(tài)。
Java里面可以將wait()notify()放在synchronized里面,是因?yàn)镴ava是這樣處理的:

synchronized代碼被執(zhí)行期間,線程調(diào)用對象的wait()方法,會釋放對象鎖標(biāo)志,然后進(jìn)入等待狀態(tài),然后由其它線程調(diào)用notify()或者notifyAll()方法通知正在等待的線程。

并發(fā)的類

JDK1.5中增加了更多的類,以便更靈活地使用鎖機(jī)制
Lock接口、ReentrantLock類,如下:

ReadWriteLock接口、ReentrantReadWriteLock類
.writeLock(),.lock(), .readLock(),.unlock(),這些方法。

并發(fā)API(線程池) Concurrent包

java.util.concurrent包中增加了一些方便的類

常用于很少寫入而讀取頻繁的對象

CopyOnWriteArrayList、 CopyOnWriteArraySet

ConcurrentHashMap

putIfAbsent(), remove(), replace()

ArrayBlockingQueue

使用線程池 線程池相關(guān)的類

ExecutorService 接口、ThreadPoolExecutor 類

Executors 工具類
他們同樣位于Concurrent接口的實(shí)現(xiàn)下面,如下:

常見的用法

ExecutorService pool = Executors.newCachedThreadPool();

使用其execute( Runnable r)方法

代碼
import java.util.concurrent.*;
/** 創(chuàng)建線程池示例
   */
public class ExecutorDemo {
  public static void main(String[] args) {
    // 創(chuàng)建線程池對象
    ExecutorService  executor = Executors.newCachedThreadPool();
    
    // 提交任務(wù)到線程池
    executor.execute(new PrintChar("a", 4));
    executor.execute(new PrintChar("b", 2));
    executor.execute(new PrintNum(2));
    //關(guān)閉線程池
    executor.shutdown();
   }
}
class PrintChar implements Runnable {
  private char charToPrint; // The character to print
  private int times; // The times to repeat

  /** 給定打印次數(shù),打印特定字符
   */
  public PrintChar(char c, int t) {
    charToPrint = c;
    times = t;
  }

輸出結(jié)果

aaaabb 1 2
流式操作及并行流

這里是指Java8新增的函數(shù)式思想,并不是具體的文件輸入輸出流。使得某些編程語句更加流暢的表達(dá)。
比如,對數(shù)組進(jìn)行流化:

Arrays.stream(a)
    .filter( i -> i>20 )
    .map(i->i*i)
    .sorted()
    .distinct()
    .limit(10)
    .max();
stream的操作種類

流操作分成兩類:

中間的 -中間的操作保持流打開狀態(tài),并允許后續(xù)的操作。

如: filter sorted limit map

末端的 - 末端的操作必須是對流的最終操作。

如: max min count forEach findAny

流步驟

從某個(gè)源頭獲得一個(gè)流。

執(zhí)行一個(gè)或更多的中間的操作。

執(zhí)行一個(gè)末端的操作。

如何得到流

對于數(shù)組

Arrays.stream(ary)

對于collection (包括List)

list.stream()

對于Map,沒有流,但提供了類似的方法

map.putIfAbsent

map.computeIfPresent

map.merge

代碼
import java.util.*;
class UseStream
{
    public static void main(String[] args)
    {
        List a = Arrays.asList(1,2,5,7,3);
        System.out.println(
                a.stream()
                        .mapToInt(i->(int)i)
                        .filter( i -> i>2 )
                        .map( i -> i*i )
                        .sorted()
                        .distinct()
                        .limit(10)
                        .max()
        );
    }
}

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

OptionalInt[49]
流的并行計(jì)算(略)

只需將上面代碼的.stream()換成 .parallelStream()。

其他都不變,就可以實(shí)現(xiàn)并行計(jì)算

可以說,stream就是為并行運(yùn)算而生的,它封裝的并行計(jì)算的大量內(nèi)部細(xì)節(jié)。

文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/65946.html

相關(guān)文章

  • 線程編程完全指南

    摘要:在這個(gè)范圍廣大的并發(fā)技術(shù)領(lǐng)域當(dāng)中多線程編程可以說是基礎(chǔ)和核心,大多數(shù)抽象并發(fā)問題的構(gòu)思與解決都是基于多線程模型來進(jìn)行的。一般來說,多線程程序會面臨三類問題正確性問題效率問題死鎖問題。 多線程編程或者說范圍更大的并發(fā)編程是一種非常復(fù)雜且容易出錯(cuò)的編程方式,但是我們?yōu)槭裁催€要冒著風(fēng)險(xiǎn)艱辛地學(xué)習(xí)各種多線程編程技術(shù)、解決各種并發(fā)問題呢? 因?yàn)椴l(fā)是整個(gè)分布式集群的基礎(chǔ),通過分布式集群不僅可以大...

    mengera88 評論0 收藏0
  • 操作系統(tǒng):進(jìn)程、線程

    摘要:實(shí)際工作并不是非此即彼,往往都是進(jìn)程線程結(jié)合的方式。操作系統(tǒng)會保證當(dāng)線程數(shù)不大于數(shù)目時(shí),不同的線程運(yùn)行于不同的上改善程序結(jié)構(gòu)。關(guān)于操作系統(tǒng)內(nèi)部如何創(chuàng)建銷毀進(jìn)程線程,即為什么這些操作進(jìn)程消耗會比線程大,還沒有搞明白。 一、淺層理解 進(jìn)程是資源分配的最小單位,線程是CPU分配的最小單位——簡單明了的說明了進(jìn)程與線程的區(qū)別特點(diǎn),然而在實(shí)際工作中并沒有什么卵用。 二、多個(gè)維度下,進(jìn)程與線程的優(yōu)...

    Java3y 評論0 收藏0
  • 線程程序,單核cpu與核cpu如何工作相關(guān)的探討

    摘要:對多線程程序,單核與多核如何工作相關(guān)的探討我們程序員在編碼的時(shí)候,涉及到技術(shù)方案時(shí),往往會忽略掉代碼對性能方面的影響,或者沒有足夠的敏感度來幫助自己判斷自己的技術(shù)方案對系統(tǒng)性能造成的影響。 對多線程程序,單核cpu與多核cpu如何工作相關(guān)的探討 我們程序員在編碼的時(shí)候,涉及到技術(shù)方案時(shí),往往會忽略掉代碼對性能方面的影響,或者沒有足夠的敏感度來幫助自己判斷自己的技術(shù)方案對系統(tǒng)性能造成的影...

    Chiclaim 評論0 收藏0
  • 線程程序,單核cpu與核cpu如何工作相關(guān)的探討

    摘要:對多線程程序,單核與多核如何工作相關(guān)的探討我們程序員在編碼的時(shí)候,涉及到技術(shù)方案時(shí),往往會忽略掉代碼對性能方面的影響,或者沒有足夠的敏感度來幫助自己判斷自己的技術(shù)方案對系統(tǒng)性能造成的影響。 對多線程程序,單核cpu與多核cpu如何工作相關(guān)的探討 我們程序員在編碼的時(shí)候,涉及到技術(shù)方案時(shí),往往會忽略掉代碼對性能方面的影響,或者沒有足夠的敏感度來幫助自己判斷自己的技術(shù)方案對系統(tǒng)性能造成的影...

    wslongchen 評論0 收藏0
  • Java線程學(xué)習(xí)(一)Java線程入門

    摘要:最近聽很多面試的小伙伴說,網(wǎng)上往往是一篇一篇的多線程的文章,除了書籍沒有什么學(xué)習(xí)多線程的一系列文章。將此線程標(biāo)記為線程或用戶線程。 最近聽很多面試的小伙伴說,網(wǎng)上往往是一篇一篇的Java多線程的文章,除了書籍沒有什么學(xué)習(xí)多線程的一系列文章。但是僅僅憑借一兩篇文章很難對多線程有系統(tǒng)的學(xué)習(xí),而且面試的時(shí)候多線程這方面的知識往往也是考察的重點(diǎn),所以考慮之下決定寫一系列關(guān)于Java多線程的文章...

    Donne 評論0 收藏0

發(fā)表評論

0條評論

最新活動
閱讀需要支付1元查看
<