java中多線程 - 多線程中的基本方法

介紹一下線程中基本的方法使用

線程睡眠sleep()

Thread.sleep(毫秒);我們可以通過sleep方法設置讓線程睡眠。可以看到sleep是個靜態方法

public static native void sleep(long var0) throws InterruptedException;
    try {System.out.println(new Date().getSeconds());Thread.sleep(5000);System.out.println(new Date().getSeconds());} catch (InterruptedException e) {e.printStackTrace();}

setDaemon守護線程

非守護線程停止,那么守護線程自動退出

    public static void main(String[] args) {Thread thread1 = new Thread() {@Overridepublic void run() {super.run();for(int i = 0; i < 5; i ++) {System.out.println("非守護線程");}}};Thread thread2 = new Thread() {@Overridepublic void run() {for(int i = 0; i < 200; i ++) {System.out.println("守護線程");}}};thread2.setDaemon(true);thread1.start();thread2.start();}

可以很明顯的看到thread2本應該執行200次輸出,但是這里只輸出了幾行。因為當thread1執行完畢后,thread2作為守護線程就自動停止了。
1445322-20180924200402581-294795725.png

多線程join

如果執行了join方法,那么停止當前線程,先跑執行了join()的線程。相當于插隊執行。如下,在執行thread2線程的時候,如果i==20的時候,則讓thread1插隊先執行

    public static void main(String[] args) {final Thread thread1 = new Thread() {@Overridepublic void run() {super.run();for(int i = 0; i < 500; i ++) {System.out.println("thread1---" + i);}}};Thread thread2 = new Thread() {@Overridepublic void run() {for(int i = 0; i < 200; i ++) {if (i == 20) {try {//插隊執行thread1.join();} catch (InterruptedException e) {e.printStackTrace();}}System.out.println(i);}}};thread1.start();thread2.start();}

join()方法也可以傳參數long 毫秒 join(毫秒)
表示讓執行join的線程,插隊執行XXX毫秒,過了時間后,兩個線程交替執行

   public static void main(String[] args) {final Thread thread1 = new Thread() {@Overridepublic void run() {super.run();for(int i = 0; i < 500; i ++) {System.out.println("thread1---" + i);}}};Thread thread2 = new Thread() {@Overridepublic void run() {for(int i = 0; i < 200; i ++) {if (i == 20) {try {//插隊執行1毫秒thread1.join(1);} catch (InterruptedException e) {e.printStackTrace();}}System.out.println(i);}}};thread1.start();thread2.start();}

yeild 禮讓線程

yeild會讓出cpu,讓其他線程執行

    public static void main(String[] args) {final Thread thread1 = new Thread() {@Overridepublic void run() {super.run();for(int i = 0; i < 500; i ++) {System.out.println( getName() + "---" + i);}}};Thread thread2 = new Thread() {@Overridepublic void run() {for(int i = 0; i < 200; i ++) {if (i % 5 == 0) {Thread.yield();}System.out.println(getName() + "---" + i);}}};thread1.start();thread2.start();}

setPriority給線程設置優先級

默認優先級是5 最小1,最大10
越大優先級越高

public static void main(String[] args) {final Thread thread1 = new Thread() {@Overridepublic void run() {super.run();for(int i = 0; i < 500; i ++) {System.out.println( getName() + "---" + i);}}};Thread thread2 = new Thread() {@Overridepublic void run() {for(int i = 0; i < 500; i ++) {System.out.println(getName() + "---" + i);}}};//設置最大的線程優先級最大為10thread1.setPriority(Thread.MIN_PRIORITY);//設置最小的線程優先級,最小為1thread2.setPriority(Thread.MAX_PRIORITY);thread1.start();thread2.start();}

synchronized

同步代碼塊

當多線程并發,多段代碼同時執行的時候。希望在執行其中代碼的時候,cpu不切換線程

不用synchronized的情況

我們來看一下不用synchronized的情況會發生什么

public class ThreadSynchronied {public static void main(String[] args) {final Say say = new Say();Thread thread1 = new Thread() {@Overridepublic void run() {for (int i = 0 ; i < 10000 ; i ++) {say.say();}}};Thread thread2 = new Thread() {@Overridepublic void run() {for (int i = 0 ; i < 10000 ; i ++) {say.say1();}}};//設置最大的線程優先級最大為10thread1.setPriority(Thread.MIN_PRIORITY);//設置最小的線程優先級,最小為1thread2.setPriority(Thread.MAX_PRIORITY);thread1.start();thread2.start();}
}class Say {void say() {System.out.print("s ");System.out.print("a ");System.out.print("y ");System.out.print("h ");System.out.print("e ");System.out.print("l ");System.out.print("l ");System.out.println("o");}void say1() {System.out.print("1 ");System.out.print("2 ");System.out.print("3 ");System.out.print("4 ");System.out.print("5 ");System.out.print("6 ");System.out.print("7 ");System.out.println("8");}
}

1445322-20180924201221861-184513208.png

我們發現有些輸出并沒有打印全,在執行線程thread1的過程中,cpu被thread2搶占。這種情況下,肯定是不符合我們的業務邏輯的。所以我們要保證線程執行了一個完整的方法后,cpu才會被其他線程搶占

使用synchronized

public class ThreadSynchronied {public static void main(String[] args) {final Say say = new Say();Thread thread1 = new Thread() {@Overridepublic void run() {for (int i = 0 ; i < 10000 ; i ++) {say.say();}}};Thread thread2 = new Thread() {@Overridepublic void run() {for (int i = 0 ; i < 10000 ; i ++) {say.say1();}}};//設置最大的線程優先級最大為10thread1.setPriority(Thread.MIN_PRIORITY);//設置最小的線程優先級,最小為1thread2.setPriority(Thread.MAX_PRIORITY);thread1.start();thread2.start();}
}class Say {String s = "hahaah";void say() {synchronized (s) {System.out.print("s ");System.out.print("a ");System.out.print("y ");System.out.print("h ");System.out.print("e ");System.out.print("l ");System.out.print("l ");System.out.println("o");}}void say1() {synchronized (s) {System.out.print("1 ");System.out.print("2 ");System.out.print("3 ");System.out.print("4 ");System.out.print("5 ");System.out.print("6 ");System.out.print("7 ");System.out.println("8");}}
}

1445322-20180924201313867-1916616418.png

使用synchronized同步代碼塊后,就發現不會出現上述情況了

同步方法

public class ThreadSynchroniedMethod {public static void main(String[] args) {final Say say = new Say();Thread thread1 = new Thread() {@Overridepublic void run() {for (int i = 0 ; i < 10000 ; i ++) {say.say();}}};Thread thread2 = new Thread() {@Overridepublic void run() {for (int i = 0 ; i < 10000 ; i ++) {say.say1();}}};//設置最大的線程優先級最大為10thread1.setPriority(Thread.MIN_PRIORITY);//設置最小的線程優先級,最小為1thread2.setPriority(Thread.MAX_PRIORITY);thread1.start();thread2.start();}
}class Say {//在方法上加鎖static synchronized void say() {System.out.print("s ");System.out.print("a ");System.out.print("y ");System.out.print("h ");System.out.print("e ");System.out.print("l ");System.out.print("l ");System.out.println("o");}static void say1() {synchronized (Say.class) {System.out.print("1 ");System.out.print("2 ");System.out.print("3 ");System.out.print("4 ");System.out.print("5 ");System.out.print("6 ");System.out.print("7 ");System.out.println("8");}}
}

同步方法指的就是在方法上加鎖

靜態同步方法的所對象是該類的字節碼對象
非靜態的同步方法鎖對象是this

多個線程使用同一資源鎖,容易造成死鎖

什么是死鎖?

死鎖是指兩個或兩個以上的進程在執行過程中,由于競爭資源或者由于彼此通信而造成的一種阻塞的現象,若無外力作用,它們都將無法推進下去。此時稱系統處于死鎖狀態或系統產生了死鎖,這些永遠在互相等待的進程稱為死鎖進程。

線程安全類

Vector
StringBuffer
HashTable

線程不安全

ArrayList
StringBuilder
HashSet

java.util.Collections中有synchronizedList等方法,支持我們把線程不安全的集合轉成線程安全的
1445322-20180924201344939-511625922.png

學習筆記

多次啟動一個線程是非法的

轉載于:https://www.cnblogs.com/amberbar/p/9696440.html

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/249437.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/249437.shtml
英文地址,請注明出處:http://en.pswp.cn/news/249437.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

nodejs匿名函數

https://www.cnblogs.com/sharpest/p/8056232.html

Deployment descriptor

Deployment descriptor 是指一種配置文件用于工件部署到一些container/engine。 在Java Platform&#xff0c;Enterprise Edition中&#xff0c;部署描述符描述了應如何部署組件&#xff0c;模塊或應用程序&#xff08;如Web應用程序或企業應用程序&#xff09;。它指示部署工具…

cordova 一個將web應用程序封裝成app的框架

cordova 一個將web應用程序封裝成app的框架 cordova的詳細介紹請參考這個鏈接&#xff1a;http://www.zhoujingen.cn/blog/7034.html 我接下來主要將如何搭建。 1.首先你需要下載幾樣東西 1.jdk. 2.android_SDK. 2.安裝這兩個&#xff0c;并配置環境變量 這里jdk的環境變量配置…

windows linux 子系統折騰記

最近買了部新電腦&#xff0c;海爾n4105的一體機&#xff0c;好像叫s7。 放在房間里面&#xff0c;看看資料。因為性能孱弱&#xff0c;所以不敢安裝太強大的軟件&#xff0c;然后又有一顆折騰的心。所以嘗試了win10自帶的linux子系統。然后在應用商店搜索linux推薦debian 系統…

nodejs閉包

一、什么是閉包&#xff1f; 官方”的解釋是&#xff1a;閉包是一個擁有許多變量和綁定了這些變量的環境的表達式&#xff08;通常是一個函數&#xff09;&#xff0c;因而這些變量也是該表達式的一部分。 相信很少有人能直接看懂這句話&#xff0c;因為他描述的太學術。其實這…

《深入理解Java虛擬機》讀書筆記八

第九章 類加載及執行子系統的案例與實戰 Q&#xff1a;如果有10個WEB應用程序都是用Spring來進行組織管理的話&#xff0c;可以把Spring放到Common或Shared目錄下&#xff08;Tomcat5.0&#xff09;讓這些程序共享。Spring要對用戶程序的類進行管理&#xff0c;自然要能訪問到用…

一些非常有用的鏈接和工具

微信公眾平臺SDK Senparc.Weixin for C#&#xff0c;支持.NET Framework及.NET Core &#xff1a; https://github.com/JeffreySu/WeiXinMPSDK layui開發文檔地址&#xff1a;https://www.layui.com/doc/ .Net Core GitHub社區 &#xff1a; https://github.com/dotnetcore EF…

Activity Intent相關FLAG介紹

先首先簡單介紹下Task和Activity的關系 Task就像一個容器&#xff0c;而Activity就相當與填充這個容器的東西&#xff0c;第一個東西&#xff08;Activity&#xff09;則會處于最下面&#xff0c;最后添加的東西&#xff08;Activity&#xff09;則會在最上面。從Task中取出東西…

js的原型和原型鏈

構造函數創建對象&#xff1a; function Person() {} var person new Person(); person.name Kevin; console.log(person.name) // KevinPerson 就是一個構造函數&#xff0c;我們使用 new 創建了一個實例對象 person prototype 每個函數都有一個 prototype 屬性 每一個Ja…

二維數組

要求&#xff1a;求一個二維數組的最大子數組和 思路&#xff1a;對于這個題&#xff0c;我會最簡單的讀取&#xff0c;雖然在網上查到了代碼&#xff0c;但是查找最大子數組的循環我真的看不懂&#xff0c;也不是特別懂思路&#xff0c;所以在這不會寫思路 package 二維數組; …

資源

資源鏈接&#xff1a; 內存池TinySTLminiSTLcghSTL1. lishuhuakai 2. 轉載于:https://www.cnblogs.com/sunbines/p/9707483.html

Android判斷應用或Activity是否存在

一、根據包名判斷應用是否存在public boolean checkApplication(String packageName) { if (packageName null || "".equals(packageName)){ return false; } try { ApplicationInfo info getPackageManager().getApplicationInfo(packageName, PackageManager.GET…

vue ref

https://www.jianshu.com/p/623c8b009a85

033 Url中特殊字符的處理

在url跳轉頁面的時候&#xff0c;參數值中的#不見了&#xff0c;一直沒有處理&#xff0c;今天有空看了一下&#xff0c;后來發現后臺的過濾器之類的都沒有處理&#xff0c;就比較奇怪了&#xff0c;原來是特殊字符的問題。 一&#xff1a;Url中的特殊字符 1.說明 這里還是需要…

Effective Java(1)-創建和銷毀對象

Effective Java&#xff08;1&#xff09;-創建和銷毀對象 轉載于:https://www.cnblogs.com/Johar/p/10556218.html

什么是Affinity

什么是Affinity 在某些情況下&#xff0c;Android需要知道一個Activity屬于哪個Task&#xff0c;即使它沒有被啟動到一個具體的Task里。這是通過任務共用性&#xff08;Affinities&#xff09;完成的。任務共用性&#xff08;Affinities&#xff09;為這個運行一個或多…

vue this

https://blog.csdn.net/cddcj/article/details/80866902

課外書——自控力(斯坦福大學最受歡迎的心理學課程)

01我要做&#xff0c;我不要&#xff0c;我想要&#xff1a;什么是意志力&#xff1f;為什么意志力&#xff1f;為什么意志力至關重要&#xff1f; 核心思想&#xff1a; 意志力實際上是“我要做”、“我不要”和“我想要”這三種力量。它們協同努力&#xff0c;讓我們變成更好…

Docker運行GUI軟件的方法

轉自 https://www.csdn.net/article/2015-07-30/2825340 簡介&#xff1a; Docker通過namespace將容器與主機上的網絡和運行環境進行了隔離&#xff0c;默認情況下&#xff0c;在容器中運行帶界面的軟件在外部是看不到的。在這個分享中&#xff0c;將介紹通過共享X11套接字讓外…

JS正則表達式驗證數字非常全

驗證數字的正則表達式集 驗證數字&#xff1a;^[0-9]*$ 驗證n位的數字&#xff1a;^\d{n}$ 驗證至少n位數字&#xff1a;^\d{n,}$ 驗證m-n位的數字&#xff1a;^\d{m,n}$ 驗證零和非零開頭的數字&#xff1a;^(0|[1-9][0-9]*)$ 驗證有兩位小數的正實數&#xff1a;^[0-9](.[0-9…