国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

java高并發(fā)系列 - 第6天:線程的基本操作

Youngdze / 2732人閱讀

摘要:終止線程一般來說線程執(zhí)行完畢就會結(jié)束,無需手動關(guān)閉。線程正在運行過程中,被強制結(jié)束了,可能會導(dǎo)致一些意想不到的后果。其中和表示兩個線程。這樣做的目的是使其他等待在對象上的線程不至于因為的休眠而全部無法正常執(zhí)行。

新建線程

新建線程很簡單。只需要使用new關(guān)鍵字創(chuàng)建一個線程對象,然后調(diào)用它的start()啟動線程即可。

Thread thread1 = new Thread1();
t1.start();

那么線程start()之后,會干什么呢?線程有個run()方法,start()會創(chuàng)建一個新的線程并讓這個線程執(zhí)行run()方法。

這里需要注意,下面代碼也能通過編譯,也能正常執(zhí)行。但是,卻不能新建一個線程,而是在當(dāng)前線程中調(diào)用run()方法,將run方法只是作為一個普通的方法調(diào)用。

Thread thread1 = new Thread1();
thread1.run();

所以,希望大家注意,調(diào)用start方法和直接調(diào)用run方法的區(qū)別。

start方法是啟動一個線程,run方法只會在當(dāng)前線程中串行的執(zhí)行run方法中的代碼。

默認(rèn)情況下, 線程的run方法什么都沒有,啟動一個線程之后馬上就結(jié)束了,所以如果你需要線程做點什么,需要把您的代碼寫到run方法中,所以必須重寫run方法。

Thread thread1 = new Thread() {
            @Override
            public void run() {
                System.out.println("hello,我是一個線程!");
            }
        };
thread1.start();

上面是使用匿名內(nèi)部類實現(xiàn)的,重寫了Thread的run方法,并且打印了一條信息。我們可以通過繼承Thread類,然后重寫run方法,來自定義一個線程。但考慮java是單繼承的,從擴展性上來說,我們實現(xiàn)一個接口來自定義一個線程更好一些,java中剛好提供了Runnable接口來自定義一個線程。

@FunctionalInterface
public interface Runnable {
    public abstract void run();
}

Thread類有一個非常重要的構(gòu)造方法:

public Thread(Runnable target)
我們在看一下Thread的run方法:

public void run() {
        if (target != null) {
            target.run();
        }
    }

當(dāng)我們啟動線程的start方法之后,線程會執(zhí)行run方法,run方法中會調(diào)用Thread構(gòu)造方法傳入的target的run方法。

實現(xiàn)Runnable接口是比較常見的做法,也是推薦的做法。

終止線程

一般來說線程執(zhí)行完畢就會結(jié)束,無需手動關(guān)閉。但是如果我們想關(guān)閉一個正在運行的線程,有什么方法呢?可以看一下Thread類中提供了一個stop()方法,調(diào)用這個方法,就可以立即將一個線程終止,非常方便。

package com.itsoku.chat01;

import lombok.extern.slf4j.Slf4j;
import java.util.concurrent.TimeUnit;

/**
 * description
* time:2019/7/12 17:18
* author:專注于java技術(shù)分享(帶你玩轉(zhuǎn) 爬蟲、分布式事務(wù)、異步消息服務(wù)、任務(wù)調(diào)度、分庫分表、大數(shù)據(jù)等),喜歡請關(guān)注! */ @Slf4j public class Demo01 { public static void main(String[] args) throws InterruptedException { Thread thread1 = new Thread() { @Override public void run() { log.info("start"); boolean flag = true; while (flag) { ; } log.info("end"); } }; thread1.setName("thread1"); thread1.start(); //當(dāng)前線程休眠1秒 TimeUnit.SECONDS.sleep(1); //關(guān)閉線程thread1 thread1.stop(); //輸出線程thread1的狀態(tài) log.info("{}", thread1.getState()); //當(dāng)前線程休眠1秒 TimeUnit.SECONDS.sleep(1); //輸出線程thread1的狀態(tài) log.info("{}", thread1.getState()); } }

運行代碼,輸出:

18:02:15.312 [thread1] INFO com.itsoku.chat01.Demo01 - start
18:02:16.311 [main] INFO com.itsoku.chat01.Demo01 - RUNNABLE
18:02:17.313 [main] INFO com.itsoku.chat01.Demo01 - TERMINATED
代碼中有個死循環(huán),調(diào)用stop方法之后,線程thread1的狀態(tài)變?yōu)門ERMINATED(結(jié)束狀態(tài)),線程停止了。

我們使用idea或者eclipse的時候,會發(fā)現(xiàn)這個方法是一個廢棄的方法,也就是說,在將來,jdk可能就會移除該方法。

stop方法為何會被廢棄而不推薦使用?stop方法過于暴力,強制把正在執(zhí)行的方法停止了。

大家是否遇到過這樣的場景:電力系統(tǒng)需要維修,此時咱們正在寫代碼,維修人員直接將電源關(guān)閉了,代碼還沒保存的,是不是很崩潰,這種方式就像直接調(diào)用線程的stop方法類似。線程正在運行過程中,被強制結(jié)束了,可能會導(dǎo)致一些意想不到的后果。可以給大家發(fā)送一個通知,告訴大家保存一下手頭的工作,將電腦關(guān)閉。

線程中斷

在java中,線程中斷是一種重要的線程寫作機制,從表面上理解,中斷就是讓目標(biāo)線程停止執(zhí)行的意思,實際上并非完全如此。在上面中,我們已經(jīng)詳細(xì)討論了stop方法停止線程的壞處,jdk中提供了更好的中斷線程的方法。嚴(yán)格的說,線程中斷并不會使線程立即退出,而是給線程發(fā)送一個通知,告知目標(biāo)線程,有人希望你退出了!至于目標(biāo)線程接收到通知之后如何處理,則完全由目標(biāo)線程自己決定,這點很重要,如果中斷后,線程立即無條件退出,我們又會到stop方法的老問題。

Thread提供了3個與線程中斷有關(guān)的方法,這3個方法容易混淆,大家注意下:

public void interrupt() //中斷線程
public boolean isInterrupted() //判斷線程是否被中斷
public static boolean interrupted() //判斷線程是否被中斷,并清除當(dāng)前中斷狀態(tài)
interrupt()方法是一個實例方法,它通知目標(biāo)線程中斷,也就是設(shè)置中斷標(biāo)志位為true,中斷標(biāo)志位表示當(dāng)前線程已經(jīng)被中斷了。isInterrupted()方法也是一個實例方法,它判斷當(dāng)前線程是否被中斷(通過檢查中斷標(biāo)志位)。最后一個方法interrupted()是一個靜態(tài)方法,返回boolean類型,也是用來判斷當(dāng)前線程是否被中斷,但是同時會清除當(dāng)前線程的中斷標(biāo)志位的狀態(tài)。

while (true) {
            if (this.isInterrupted()) {
                System.out.println("我要退出了!");
                break;
            }
        }
    }
};
thread1.setName("thread1");
thread1.start();
TimeUnit.SECONDS.sleep(1);
thread1.interrupt();

上面代碼中有個死循環(huán),interrupt()方法被調(diào)用之后,線程的中斷標(biāo)志將被置為true,循環(huán)體中通過檢查線程的中斷標(biāo)志是否為ture(this.isInterrupted())來判斷線程是否需要退出了。

再看一種中斷的方法:

static volatile boolean isStop = false;

public static void main(String[] args) throws InterruptedException {
    Thread thread1 = new Thread() {
        @Override
        public void run() {
            while (true) {
                if (isStop) {
                    System.out.println("我要退出了!");
                    break;
                }
            }
        }
    };
    thread1.setName("thread1");
    thread1.start();
    TimeUnit.SECONDS.sleep(1);
    isStop = true;
}

代碼中通過一個變量isStop來控制線程是否停止。

通過變量控制和線程自帶的interrupt方法來中斷線程有什么區(qū)別呢?

如果一個線程調(diào)用了sleep方法,一直處于休眠狀態(tài),通過變量控制,還可以中斷線程么?大家可以思考一下。

此時只能使用線程提供的interrupt方法來中斷線程了。

public static void main(String[] args) throws InterruptedException {
    Thread thread1 = new Thread() {
        @Override
        public void run() {
            while (true) {
                //休眠100秒
                try {
                    TimeUnit.SECONDS.sleep(100);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println("我要退出了!");
                break;
            }
        }
    };
    thread1.setName("thread1");
    thread1.start();
    TimeUnit.SECONDS.sleep(1);
    thread1.interrupt();
}

調(diào)用interrupt()方法之后,線程的sleep方法將會拋出InterruptedException異常。

Thread thread1 = new Thread() {
    @Override
    public void run() {
        while (true) {
            //休眠100秒
            try {
                TimeUnit.SECONDS.sleep(100);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            if (this.isInterrupted()) {
                System.out.println("我要退出了!");
                break;
            }
        }
    }
};

運行上面的代碼,發(fā)現(xiàn)程序無法終止。為什么?

代碼需要改為:

Thread thread1 = new Thread() {
    @Override
    public void run() {
        while (true) {
            //休眠100秒
            try {
                TimeUnit.SECONDS.sleep(100);
            } catch (InterruptedException e) {
                this.interrupt();
                e.printStackTrace();
            }
            if (this.isInterrupted()) {
                System.out.println("我要退出了!");
                break;
            }
        }
    }
};

上面代碼可以終止。

注意:sleep方法由于中斷而拋出異常之后,線程的中斷標(biāo)志會被清除(置為false),所以在異常中需要執(zhí)行this.interrupt()方法,將中斷標(biāo)志位置為true

等待(wait)和通知(notify)

為了支持多線程之間的協(xié)作,JDK提供了兩個非常重要的方法:等待wait()方法和通知notify()方法。這2個方法并不是在Thread類中的,而是在Object類中定義的。這意味著所有的對象都可以調(diào)用者兩個方法。

public final void wait() throws InterruptedException;
public final native void notify();

當(dāng)在一個對象實例上調(diào)用wait()方法后,當(dāng)前線程就會在這個對象上等待。這是什么意思?比如在線程A中,調(diào)用了obj.wait()方法,那么線程A就會停止繼續(xù)執(zhí)行,轉(zhuǎn)為等待狀態(tài)。等待到什么時候結(jié)束呢?線程A會一直等到其他線程調(diào)用obj.notify()方法為止,這時,obj對象成為了多個線程之間的有效通信手段。

那么wait()方法和notify()方法是如何工作的呢?如圖2.5展示了兩者的工作過程。如果一個線程調(diào)用了object.wait()方法,那么它就會進出object對象的等待隊列。這個隊列中,可能會有多個線程,因為系統(tǒng)可能運行多個線程同時等待某一個對象。當(dāng)object.notify()方法被調(diào)用時,它就會從這個隊列中隨機選擇一個線程,并將其喚醒。這里希望大家注意一下,這個選擇是不公平的,并不是先等待線程就會優(yōu)先被選擇,這個選擇完全是隨機的。

除notify()方法外,Object獨享還有一個nofiyAll()方法,它和notify()方法的功能類似,不同的是,它會喚醒在這個等待隊列中所有等待的線程,而不是隨機選擇一個。

這里強調(diào)一點,Object.wait()方法并不能隨便調(diào)用。它必須包含在對應(yīng)的synchronize語句匯總,無論是wait()方法或者notify()方法都需要首先獲取目標(biāo)獨享的一個監(jiān)視器。圖2.6顯示了wait()方法和nofiy()方法的工作流程細(xì)節(jié)。其中T1和T2表示兩個線程。T1在正確執(zhí)行wait()方法錢,必須獲得object對象的監(jiān)視器。而wait()方法在執(zhí)行后,會釋放這個監(jiān)視器。這樣做的目的是使其他等待在object對象上的線程不至于因為T1的休眠而全部無法正常執(zhí)行。

線程T2在notify()方法調(diào)用前,也必須獲得object對象的監(jiān)視器。所幸,此時T1已經(jīng)釋放了這個監(jiān)視器,因此,T2可以順利獲得object對象的監(jiān)視器。接著,T2執(zhí)行了notify()方法嘗試喚醒一個等待線程,這里假設(shè)喚醒了T1。T1在被喚醒后,要做的第一件事并不是執(zhí)行后續(xù)代碼,而是要嘗試重新獲得object對象的監(jiān)視器,而這個監(jiān)視器也正是T1在wait()方法執(zhí)行前所持有的那個。如果暫時無法獲得,則T1還必須等待這個監(jiān)視器。當(dāng)監(jiān)視器順利獲得后,T1才可以在真正意義上繼續(xù)執(zhí)行。

給大家上個例子:

package com.itsoku.chat01;

/**
 * description
* time:2019/7/12 17:18
* author專注于java技術(shù)分享(帶你玩轉(zhuǎn) 爬蟲、分布式事務(wù)、異步消息服務(wù)、任務(wù)調(diào)度、分庫分表、大數(shù)據(jù)等),喜歡請關(guān)注! */ public class Demo06 { static Object object = new Object(); public static class T1 extends Thread { @Override public void run() { synchronized (object) { System.out.println(System.currentTimeMillis() + ":T1 start!"); try { System.out.println(System.currentTimeMillis() + ":T1 wait for object"); object.wait(); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(System.currentTimeMillis() + ":T1 end!"); } } } public static class T2 extends Thread { @Override public void run() { synchronized (object) { System.out.println(System.currentTimeMillis() + ":T2 start,notify one thread! "); object.notify(); System.out.println(System.currentTimeMillis() + ":T2 end!"); try { Thread.sleep(2000); } catch (InterruptedException e) { e.printStackTrace(); } } } } public static void main(String[] args) throws InterruptedException { new T1().start(); new T2().start(); } }

運行結(jié)果:

1562934497212:T1 start!
1562934497212:T1 wait for object
1562934497212:T2 start,notify one thread!
1562934497212:T2 end!
1562934499213:T1 end!
注意下打印結(jié)果,T2調(diào)用notify方法之后,T1并不能立即繼續(xù)執(zhí)行,而是要等待T2釋放objec投遞鎖之后,T1重新成功獲取鎖后,才能繼續(xù)執(zhí)行。因此最后2行日志相差了2秒(因為T2調(diào)用notify方法后休眠了2秒)。

注意:Object.wait()方法和Thread.sleeep()方法都可以讓現(xiàn)場等待若干時間。除wait()方法可以被喚醒外,另外一個主要的區(qū)別就是wait()方法會釋放目標(biāo)對象的鎖,而Thread.sleep()方法不會釋放鎖。

再給大家講解一下wait(),notify(),notifyAll(),加深一下理解:

可以這么理解,obj對象上有2個隊列,如圖1,q1:等待隊列,q2:準(zhǔn)備獲取鎖的隊列;兩個隊列都為空。

obj.wait()過程:

synchronize(obj){
    obj.wait();
}

假如有3個線程,t1、t2、t3同時執(zhí)行上面代碼,t1、t2、t3會進入q2隊列,如圖2,進入q2的隊列的這些線程才有資格去爭搶obj的鎖,假設(shè)t1爭搶到了,那么t2、t3機型在q2中等待著獲取鎖,t1進入代碼塊執(zhí)行wait()方法,此時t1會進入q1隊列,然后系統(tǒng)會通知q2隊列中的t2、t3去爭搶obj的鎖,搶到之后過程如t1的過程。最后t1、t2、t3都進入了q1隊列,如圖3。

上面過程之后,又來了線程t4執(zhí)行了notify()方法,如下:**

synchronize(obj){
    obj.notify();
}

t4會獲取到obj的鎖,然后執(zhí)行notify()方法,系統(tǒng)會從q1隊列中隨機取一個線程,將其加入到q2隊列,假如t2運氣比較好,被隨機到了,然后t2進入了q2隊列,如圖4,進入q2的隊列的鎖才有資格爭搶obj的鎖,t4線程執(zhí)行完畢之后,會釋放obj的鎖,此時隊列q2中的t2會獲取到obj的鎖,然后繼續(xù)執(zhí)行,執(zhí)行完畢之后,q1中包含t1、t3,q2隊列為空,如圖5

接著又來了個t5隊列,執(zhí)行了notifyAll()方法,如下:

synchronize(obj){
    obj.notifyAll();
}

2.調(diào)用obj.wait()方法,當(dāng)前線程會加入隊列queue1,然后會釋放obj對象的鎖

t5會獲取到obj的鎖,然后執(zhí)行notifyAll()方法,系統(tǒng)會將隊列q1中的線程都移到q2中,如圖6,t5線程執(zhí)行完畢之后,會釋放obj的鎖,此時隊列q2中的t1、t3會爭搶obj的鎖,爭搶到的繼續(xù)執(zhí)行,未增強到的帶鎖釋放之后,系統(tǒng)會通知q2中的線程繼續(xù)爭搶索,然后繼續(xù)執(zhí)行,最后兩個隊列中都為空了。

掛起(suspend)和繼續(xù)執(zhí)行(resume)線程

Thread類中還有2個方法,即線程掛起(suspend)和繼續(xù)執(zhí)行(resume),這2個操作是一對相反的操作,被掛起的線程,必須要等到resume()方法操作后,才能繼續(xù)執(zhí)行。系統(tǒng)中已經(jīng)標(biāo)注著2個方法過時了,不推薦使用。

系統(tǒng)不推薦使用suspend()方法去掛起線程是因為suspend()方法導(dǎo)致線程暫停的同時,并不會釋放任何鎖資源。此時,其他任何線程想要訪問被它占用的鎖時,都會被牽連,導(dǎo)致無法正常運行(如圖2.7所示)。直到在對應(yīng)的線程上進行了resume()方法操作,被掛起的線程才能繼續(xù),從而其他所有阻塞在相關(guān)鎖上的線程也可以繼續(xù)執(zhí)行。但是,如果resume()方法操作意外地在suspend()方法前就被執(zhí)行了,那么被掛起的線程可能很難有機會被繼續(xù)執(zhí)行了。并且,更嚴(yán)重的是:它所占用的鎖不會被釋放,因此可能會導(dǎo)致整個系統(tǒng)工作不正常。而且,對于被掛起的線程,從它線程的狀態(tài)上看,居然還是Runnable狀態(tài),這也會影響我們隊系統(tǒng)當(dāng)前狀態(tài)的判斷。

上個例子:

/**
 * description
* time:2019/7/12 17:18
* author:專注于java技術(shù)分享(帶你玩轉(zhuǎn) 爬蟲、分布式事務(wù)、異步消息服務(wù)、任務(wù)調(diào)度、分庫分表、大數(shù)據(jù)等),喜歡請關(guān)注! */ public class Demo07 { static Object object = new Object(); public static class T1 extends Thread { public T1(String name) { super(name); } @Override public void run() { synchronized (object) { System.out.println("in " + this.getName()); Thread.currentThread().suspend(); } } } public static void main(String[] args) throws InterruptedException { T1 t1 = new T1("t1"); t1.start(); Thread.sleep(100); T1 t2 = new T1("t2"); t2.start(); t1.resume(); t2.resume(); t1.join(); t2.join(); } }

運行代碼輸出:

in t1
in t2
我們會發(fā)現(xiàn)程序不會結(jié)束,線程t2被掛起了,導(dǎo)致程序無法結(jié)束,使用jstack命令查看線程堆棧信息可以看到:

"t2" #13 prio=5 os_prio=0 tid=0x000000002796c000 nid=0xa3c runnable [0x000000002867f000]
java.lang.Thread.State: RUNNABLE

    at java.lang.Thread.suspend0(Native Method)
    at java.lang.Thread.suspend(Thread.java:1029)
    at com.itsoku.chat01.Demo07$T1.run(Demo07.java:20)
    - locked <0x0000000717372fc0> (a java.lang.Object)

發(fā)現(xiàn)t2線程在suspend0處被掛起了,t2的狀態(tài)竟然還是RUNNABLE狀態(tài),線程明明被掛起了,狀態(tài)還是運行中容易導(dǎo)致我們隊當(dāng)前系統(tǒng)進行誤判,代碼中已經(jīng)調(diào)用resume()方法了,但是由于時間先后順序的緣故,resume并沒有生效,這導(dǎo)致了t2永遠(yuǎn)滴被掛起了,并且永遠(yuǎn)占用了object的鎖,這對于系統(tǒng)來說可能是致命的。

等待線程結(jié)束(join)和謙讓(yeild)

很多時候,一個線程的輸入可能非常依賴于另外一個或者多個線程的輸出,此時,這個線程就需要等待依賴的線程執(zhí)行完畢,才能繼續(xù)執(zhí)行。jdk提供了join()操作來實現(xiàn)這個功能。如下所示,顯示了2個join()方法:

public final void join() throws InterruptedException;
public final synchronized void join(long millis) throws InterruptedException;
第1個方法表示無限等待,它會一直只是當(dāng)前線程。知道目標(biāo)線程執(zhí)行完畢。

第2個方法有個參數(shù),用于指定等待時間,如果超過了給定的時間目標(biāo)線程還在執(zhí)行,當(dāng)前線程也會停止等待,而繼續(xù)往下執(zhí)行。

比如:線程T1需要等待T2、T3完成之后才能繼續(xù)執(zhí)行,那么在T1線程中需要分別調(diào)用T2和T3的join()方法。

上個示例:

/**
 * description
* time:2019/7/12 17:18
* author:專注于java技術(shù)分享(帶你玩轉(zhuǎn) 爬蟲、分布式事務(wù)、異步消息服務(wù)、任務(wù)調(diào)度、分庫分表、大數(shù)據(jù)等),喜歡請關(guān)注! */ public class Demo08 { static int num = 0; public static class T1 extends Thread { public T1(String name) { super(name); } @Override public void run() { System.out.println(System.currentTimeMillis() + ",start " + this.getName()); for (int i = 0; i < 10; i++) { num++; try { Thread.sleep(200); } catch (InterruptedException e) { e.printStackTrace(); } } System.out.println(System.currentTimeMillis() + ",end " + this.getName()); } } public static void main(String[] args) throws InterruptedException { T1 t1 = new T1("t1"); t1.start(); t1.join(); System.out.println(System.currentTimeMillis() + ",num = " + num); } }

執(zhí)行結(jié)果:

1562939889129,start t1
1562939891134,end t1
1562939891134,num = 10
num的結(jié)果為10,1、3行的時間戳相差2秒左右,說明主線程等待t1完成之后才繼續(xù)執(zhí)行的。

看一下jdk1.8中Thread.join()方法的實現(xiàn):

public final synchronized void join(long millis) throws InterruptedException {

long base = System.currentTimeMillis();
long now = 0;

if (millis < 0) {
    throw new IllegalArgumentException("timeout value is negative");
}

if (millis == 0) {
    while (isAlive()) {
        wait(0);
    }
} else {
    while (isAlive()) {
        long delay = millis - now;
        if (delay <= 0) {
            break;
        }
        wait(delay);
        now = System.currentTimeMillis() - base;
    }
}

}
從join的代碼中可以看出,在被等待的線程上使用了synchronize,調(diào)用了它的wait()方法,線程最后執(zhí)行完畢之后,系統(tǒng)會自動調(diào)用它的notifyAll()方法,喚醒所有在此線程上等待的其他線程。

注意:被等待的線程執(zhí)行完畢之后,系統(tǒng)自動會調(diào)用該線程的notifyAll()方法。所以一般情況下,我們不要去在線程對象上使用wait()、notify()、notifyAll()方法。

另外一個方法是Thread.yield(),他的定義如下:

public static native void yield();
yield是謙讓的意思,這是一個靜態(tài)方法,一旦執(zhí)行,它會讓當(dāng)前線程出讓CPU,但需要注意的是,出讓CPU并不是說不讓當(dāng)前線程執(zhí)行了,當(dāng)前線程在出讓CPU后,還會進行CPU資源的爭奪,但是能否再搶到CPU的執(zhí)行權(quán)就不一定了。因此,對Thread.yield()方法的調(diào)用好像就是在說:我已經(jīng)完成了一些主要的工作,我可以休息一下了,可以讓CPU給其他線程一些工作機會了。

如果覺得一個線程不太重要,或者優(yōu)先級比較低,而又擔(dān)心此線程會過多的占用CPU資源,那么可以在適當(dāng)?shù)臅r候調(diào)用一下Thread.yield()方法,給與其他線程更多的機會。

總結(jié)

創(chuàng)建線程的2中方式:繼承Thread類;實現(xiàn)Runnable接口
啟動線程:調(diào)用線程的start()方法
終止線程:調(diào)用線程的stop()方法,方法已過時,建議不要使用
線程中斷相關(guān)的方法:調(diào)用線程實例interrupt()方法將中斷標(biāo)志置為true;使用線程實例方法isInterrupted()獲取中斷標(biāo)志;調(diào)用Thread的靜態(tài)方法interrupted()獲取線程是否被中斷,此方法調(diào)用之后會清除中斷標(biāo)志(將中斷標(biāo)志置為false了)
wait、notify、notifyAll方法,這塊比較難理解,可以回過頭去再理理
線程掛起使用線程實例方法suspend(),恢復(fù)線程使用線程實例方法resume(),這2個方法都過時了,不建議使用
等待線程結(jié)束:調(diào)用線程實例方法join()
出讓cpu資源:調(diào)用線程靜態(tài)方法yeild()

喜歡就關(guān)注我吧

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

轉(zhuǎn)載請注明本文地址:http://specialneedsforspecialkids.com/yun/76131.html

相關(guān)文章

  • java并發(fā)系列 - 19:JUC中Executor框架詳解1,全面掌握java并發(fā)相關(guān)技術(shù)

    摘要:有三種狀態(tài)運行關(guān)閉終止。類類,提供了一系列工廠方法用于創(chuàng)建線程池,返回的線程池都實現(xiàn)了接口。線程池的大小一旦達(dá)到最大值就會保持不變,在提交新任務(wù),任務(wù)將會進入等待隊列中等待。此線程池支持定時以及周期性執(zhí)行任務(wù)的需求。 這是java高并發(fā)系列第19篇文章。 本文主要內(nèi)容 介紹Executor框架相關(guān)內(nèi)容 介紹Executor 介紹ExecutorService 介紹線程池ThreadP...

    icattlecoder 評論0 收藏0
  • java并發(fā)系列 - 21javaCAS操作java并發(fā)基石

    摘要:方法由兩個參數(shù),表示期望的值,表示要給設(shè)置的新值。操作包含三個操作數(shù)內(nèi)存位置預(yù)期原值和新值。如果處的值尚未同時更改,則操作成功。中就使用了這樣的操作。上面操作還有一點是將事務(wù)范圍縮小了,也提升了系統(tǒng)并發(fā)處理的性能。 這是java高并發(fā)系列第21篇文章。 本文主要內(nèi)容 從網(wǎng)站計數(shù)器實現(xiàn)中一步步引出CAS操作 介紹java中的CAS及CAS可能存在的問題 悲觀鎖和樂觀鎖的一些介紹及數(shù)據(jù)庫...

    zorro 評論0 收藏0
  • java并發(fā)系列 - 5:深入理解進程和線程

    摘要:一旦等到期望的事件,線程就會再次進入運行狀態(tài)。表示結(jié)束狀態(tài),線程執(zhí)行完畢之后進入結(jié)束狀態(tài)。一個進程可以包括多個線程。 進程 進程(Process)是計算機中的程序關(guān)于某數(shù)據(jù)集合上的一次運行活動,是系統(tǒng)進行資源分配和調(diào)度的基本單位,是操作系統(tǒng)結(jié)構(gòu)的基礎(chǔ)。程序是指令、數(shù)據(jù)及其組織形式的描述,進程是程序的實體。 進程具有的特征: 動態(tài)性:進程是程序的一次執(zhí)行過程,是臨時的,有生命期的,是動態(tài)...

    233jl 評論0 收藏0
  • java并發(fā)系列 - 2:并發(fā)級別

    摘要:由于臨界區(qū)的存在,多線程之間的并發(fā)必須受到控制。對于非公平鎖來說,系統(tǒng)允許高優(yōu)先級的線程插隊。這樣有可能導(dǎo)致低優(yōu)先級線程產(chǎn)生饑餓。它要求所有線程都必須在有限步內(nèi)完成,這樣不會引起饑餓問題。 由于臨界區(qū)的存在,多線程之間的并發(fā)必須受到控制。根據(jù)控制并發(fā)的策略,我們可以把并發(fā)的級別分為阻塞、無饑餓、無障礙、無鎖、無等待幾種。 阻塞 一個線程是阻塞的,那么在其他線程釋放資源之前,當(dāng)前線程無法...

    Tony_Zby 評論0 收藏0
  • java并發(fā)系列 - 4:JMM相關(guān)一些概念

    摘要:我們需要先了解這些概念。在中,其表現(xiàn)在對于共享變量的某些操作,是不可分的,必須連續(xù)的完成。有序性有序性指的是程序按照代碼的先后順序執(zhí)行。 JMM(java內(nèi)存模型),由于并發(fā)程序要比串行程序復(fù)雜很多,其中一個重要原因是并發(fā)程序中數(shù)據(jù)訪問一致性和安全性將會受到嚴(yán)重挑戰(zhàn)。如何保證一個線程可以看到正確的數(shù)據(jù)呢?這個問題看起來很白癡。對于串行程序來說,根本就是小菜一碟,如果你讀取一個變量,這個...

    mengbo 評論0 收藏0
  • java并發(fā)系列 - 1:必須知道幾個概念

    摘要:并發(fā)和并行并發(fā)和并行是兩個非常容易被混淆的概念。并發(fā)說的是在一個時間段內(nèi),多件事情在這個時間段內(nèi)交替執(zhí)行。并行說的是多件事情在同一個時刻同事發(fā)生。由于線程池是一個線程,得不到執(zhí)行,而被餓死,最終導(dǎo)致了程序死鎖的現(xiàn)象。 同步(Synchronous)和異步(Asynchronous) 同步和異步通常來形容一次方法調(diào)用,同步方法調(diào)用一旦開始,調(diào)用者必須等到方法調(diào)用返回后,才能繼續(xù)后續(xù)的行為...

    zhoutk 評論0 收藏0

發(fā)表評論

0條評論

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