日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > java >内容正文

java

shadowplay要下载java_Java并发程序设计(二)Java并行程序基础

發布時間:2025/3/19 java 19 豆豆
生活随笔 收集整理的這篇文章主要介紹了 shadowplay要下载java_Java并发程序设计(二)Java并行程序基础 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

Java并行程序基礎

一、線程的生命周期

其中blocked和waiting的區別:

作者:趙老師

鏈接:https://www.zhihu.com/question/27654579/answer/128050125

來源:知乎

著作權歸作者所有。商業轉載請聯系作者獲得授權,非商業轉載請注明出處。

假設t1,t2先后兩個線程,都執行如下代碼:

synchronized(Obj) {

Obj.wait();

}

t1先進,最后在Obj.wait()下卡住,這時java管t1的狀態waitting狀態

t2后進,直接在第一行就卡住了,這時java叫t2為blocked狀態。

請注意,blocked是過去分詞,意味著他是被卡住的(無辜啊,全是淚)。因為這段代碼只讓一條線程運行。同時,jvm是知道怎么結束blocked的,只要別的線程退出這段代碼,他就會自動讓你進去。也就是說別的線程無需喚醒你,由jvm自動來干。

而waiiting是說我調用wait()等函數,主動卡住自己(我在等一個白富美),請jvm在滿足某種條件后(白富美發消息讓我們晚上見),比如另條線程調用了notify()后,把我喚醒。這個喚醒的責任在于別的線程(白富美)明確的調用一些喚醒函數。

做這樣的區分,是jvm出于管理的需要,做了這種區分,比如兩個原因的線程放兩個隊列里管理,如果別的線程運行出了synchronized這段代碼,我只需要去blocked隊列,放個出來。而某人調用了notify(),我只需要去waitting隊列里取個出來。

P.S. 從linux內核來看,這些線程都是等待狀態,沒區別,區別只在于java的管理需要。通常我們在系統級別說線程的blocked,是說線程操作io,被暫停了,這種線程由linux內核來喚醒(io設備報告數據來了,內核把block的線程放進可運行的進程隊列,依次得到處理器時間),而wait是說,等待一個內核mutex對象,另個線程signal這個mutex后,這個線程才可以運行。區別在于由誰喚醒,是操作系統,還是另一個線程,這里倒和java很相似。

二、線程的基本操作

一)新建線程

1.方法一:

Thread t=newThread();

t.start();//新建一個線程,并在該線程中調用t的run()方法。

2.方法二:

public Class MyThread implementsRunnable{public static voidmian(String[] args){

Thread t2=new Thread(newMyThread());

t2.start();

}

@Overridepublic voidrun(){

System.out.println("I am runnable man!");

}

}

二)終止線程

1.Thread中的stop()方法會直接終止線程,容易引發線程安全問題已經被棄用。

2.所以我們采用不立即中斷線程,而是給目標線程發送通知:“希望你能中斷線程的時候中斷啦!”。而什么時候中斷取決于線程自身。

public void Thread.inerrupt(); //通知線程中斷,設置中斷標志位。

public boolean Thread.isInterrupted() //判斷線程是否有中斷標志位。

public static boolean Thead.interrupted() //判斷線程是否有中斷標志位,如果有則清除標志位。

public static native void sleep(long millis) throws InterruptedException //如果當前線程被設置了中斷標志位,調用sleep方法時,

//就會拋出InterruptedException異常,該異常必須被捕獲。

三)wait和notify

兩個方法都是Object類中的方法,方法簽名為:

public final void wait() throws InterruptException;//線程停止執行轉為等待狀態,直到其他線程調用了同一實例對象的notify()或notifyAll()方法。

public final native void notify();//隨機選擇一個線程,將其喚醒。

需要強調的是,這兩個方法都不能隨便調用,它們必須包含在synchronized語句中。

例如:

public classSimpleWN {final static Object obj=newObject();public static class T1 extendsThread{

@Overridepublic voidrun(){synchronized(obj){

System.out.println(System.currentTimeMillis()+" :T1 start!");try{

System.out.println(System.currentTimeMillis()+" :wait for object!");

obj.wait();

}catch(Exception e){

e.printStackTrace();

}

System.out.println(System.currentTimeMillis()+" :T1 END!");

}

}

}public static class T2 extendsThread{

@Overridepublic voidrun(){synchronized(obj){

System.out.println(System.currentTimeMillis()+" :T2 start! notify one!");

System.out.println(System.currentTimeMillis()+" :wait for object!");

obj.notify();

System.out.println(System.currentTimeMillis()+" :T2 END!");try{

Thread.sleep(3000);

}catch(InterruptedException e) {

e.printStackTrace();

}

}

}

}public static voidmain(String[] args){

Thread t1=newT1();

Thread t2=newT2();

t1.start();

t2.start();

}

}

四)suspend和resume

– suspend()不會釋放鎖

– 如果加鎖發生在resume()之前 ,則死鎖發生

五)等待線程結束(join)和謙讓(yield)

public final void join() throws InterrupteException //一直阻塞當前線程直到目標線(調用此方法的線程)程執行完畢

public final synchronized void join(long millis) throws InterruptException //超出最大時間會繼續執行。

join線程的本質是讓調用線程wait()在當前線程對象實例上。因此不要在Thread對象實例上使用wait或者notify等類似的方法,因為這很可能影響系統API的工作。

public static native void yield() //使當前線程讓出CPU,與其他線程參與到CPU資源競爭中。

三、守護線程(Deamon)

在后臺默默地完成一些系統性的服務,比如垃圾回收線程、 JIT線程就可以理解為守護線程

當一個Java應用內,只有守護線程時,Java虛擬機就會自然退出。

設置為守護線程:

Thread t=newDaemonT();

t.setDaemon(true);

t.start();

四、實現線程同步的基本方法

關鍵字synchronized的作用是實現線程間的同步,它的工作是對同步的代碼加鎖,使得每一次只能有一個線程進入同步塊。用法:

1)對某個實例對象加鎖。

2)對對象的實例方法加鎖,相當于對當前實例加鎖。

3)對某個類的靜態方法加鎖,相當于對當前類加鎖。

public class MyRunnable implementsRunnable{static MyRunnable instance=newMyRunnable();static Object object=newObject();static int i=0;

@Overridepublic voidrun() {for(int j=0;j<1000;j++){synchronized(object) {

i++;

}

}

}public static void main(String[] args) throwsInterruptedException{

Thread t1=newThread(instance);

Thread t2=newThread(instance);

t1.start();

t2.start();

t1.join();

System.out.println(i);//1562

t2.join();

System.out.println(i);//2000

}

}

沒問題:

public class MyRunnable implementsRunnable{static MyRunnable instance=newMyRunnable();static Object object=newObject();static int i=0;public static synchronized voidincrease(){

i++;

}

@Overridepublic voidrun() {for(int j=0;j<1000;j++){

increase();

}

}public static void main(String[] args) throwsInterruptedException{

Thread t1=new Thread(newMyRunnable());

Thread t2=new Thread(newMyRunnable());

t1.start();

t2.start();

t1.join();

System.out.println(i);//1000

t2.join();

System.out.println(i);//2000

}

}

錯誤的同步方式(自行思考原因):

public class MyRunnable implementsRunnable{static MyRunnable instance=newMyRunnable();static Object object=newObject();static int i=0;public synchronized voidincrease(){

i++;

}

@Overridepublic voidrun() {for(int j=0;j<1000;j++){

increase();

}

}public static void main(String[] args) throwsInterruptedException{

Thread t1=new Thread(newMyRunnable());

Thread t2=new Thread(newMyRunnable());

t1.start();

t2.start();

t1.join();

System.out.println(i);//1747

t2.join();

System.out.println(i);//1747

}

}

五、隱蔽的錯誤

一)并發下的ArrayList

public classArrayListTest {static ArrayList list=new ArrayList<>();public static class AddThread implementsRunnable{

@Overridepublic voidrun() {for(int i=0;i<10000;i++){

list.add(i);

}

}

}public static void main(String[] args) throwsInterruptedException{

Thread t1=new Thread(newAddThread());

Thread t2=new Thread(newAddThread());

t1.start();

t2.start();

t1.join();

t2.join();

System.out.println(list.size());

}/*結果:Exception in thread "Thread-1" java.lang.ArrayIndexOutOfBoundsException: 10

at java.util.ArrayList.add(Unknown Source)

at com.tang.test.ArrayListTest$AddThread.run(ArrayListTest.java:12)

at java.lang.Thread.run(Unknown Source)

10005*/}

解決辦法:Vector代替ArrayList

二)更詭異的HashMap

解決辦法:ConcurrentHashMap代替HashMap。

三)錯誤的加鎖

public class BadLock implementsRunnable{

static Integer i=0;

static BadLock instance=newBadLock();

@Override

public voidrun() {

for(int j=0;j<10000;j++){

synchronized(i) {

i++;

}

}

}

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

Thread t1=newThread(instance);

Thread t2=newThread(instance);

t1.start(); t2.start();

t1.join(); t2.join();

System.out.println(i);

}

//結果:12862

}

總結

以上是生活随笔為你收集整理的shadowplay要下载java_Java并发程序设计(二)Java并行程序基础的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。