Java 線程多線程編程1---基礎

1、線程的基本概念


例子:


分析:


2、線程的創建和啟動


第一種線程的創建:

????定義一個線程類來實現Runner接口

例子:

package com.zhj.www;
import java.lang.Thread;
public class TestThread1 {public static void main(String[] args) {Runner1 runner1  = new Runner1();Thread myThread  = new Thread(runner1);myThread.start();//這行注釋掉的話,線程就不會執行。for(int i=0;i<100;i++) {System.out.println("Main Thread:-----" + i);}}
}
class Runner1 implements Runnable{public void  run() {for(int i = 0;i<100;i++) {System.out.println("Runner1:" + i);}}
}

運行結果:


我們會發現,主線程,和子線程是交替執行的。

但是呢,要注意:

但是若是直接調用run方法,是方法調用,兩者之間天壤之別,只有執行完成一個才會去執行另一個。


package com.zhj.www;
import java.lang.Thread;
public class TestThread1 {public static void main(String[] args) {Runner1 runner1  = new Runner1();//Thread myThread  = new Thread(runner1);runner1.run();//myThread.start();//這行注釋掉的話,線程就不會執行。for(int i=0;i<100;i++) {System.out.println("Main Thread:-----" + i);}}
}
class Runner1 implements Runnable{public void  run() {for(int i = 0;i<100;i++) {System.out.println("Runner1:" + i);}}
}
證明如下:


第二種線程的創建:

定義一個Thread的子類并重寫其run方法。

例子:

package com.zhj.www;
import java.lang.Thread;
public class TestThread1 {public static void main(String[] args) {MyThread myThread  = new MyThread();myThread.start();for(int i=0;i<100;i++) {System.out.println("Main Thread:-----" + i);}}
}
class MyThread extends Thread{public void  run() {for(int i = 0;i<100;i++) {System.out.println("Runner1:" + i);}}
}

此時,已經新建一個MyThread類繼承自Thread類,所以就不用new一個Thread 的對象出來了,而只需要new一個MyThread的子對象。然后調用其start()方法。

執行結果:


我們發現和第一種創建線程的結果是一樣的,也是交替執行。但是兩個線程分得到的時間片并不一定是相同的。

兩個方式有什么區別呢?繼承Thread類的方式(第二種方式)比較死,只能從一個類繼承,第一種方式呢?比較靈活實現接口,還可以從其他類繼承。只要能實現接口,就不要從Thread類繼承。

線程狀態轉換:




1、sleep方法:

package com.zhj.www;import java.util.*;public class TestInterrupt {public static void main(String[] args) {MyThread thread = new MyThread();thread.start();try {Thread.sleep(10000);//主線程睡眠}catch (InterruptedException e) {}//thread.interrupt();//睡著的時候打斷,太粗暴了//為什么不用它呢?thread.flag = false;}
}class MyThread extends Thread{boolean flag = true;public void run() {while(flag) {System.out.println("==="+new Date()+"===");try {sleep(1000);} catch (InterruptedException e) {return;}}}
}

運行結果:


2、join方法:


栗子:

package com.zhj.www;public class TestJoin {public static void main(String[] args) {MyThread2 t1 = new MyThread2("abcdef");t1.start();try {t1.join();//合共}catch (InterruptedException e) {}for(int i = 1;i<=10;i++) {System.out.println("I am main thread");}}
}
class MyThread2 extends Thread{public MyThread2(String s) {super(s);}public void run() {for(int i = 0; i<=10;i++) {System.out.println("I am "+ getName()+" (i:)"+i);try {sleep(1000);} catch (InterruptedException e) {return;}}}
}

運行結果:



3、yield方法:


package com.zhj.www;import java.util.*;public class TestYield {public static void main(String[] args) {MyThread3 t1 = new MyThread3("t1");MyThread3 t2  = new MyThread3("t2");t1.start();t2.start();}
}class MyThread3 extends Thread{MyThread3(String s) {super(s);}public void run() {for (int i = 1; i <= 100; i++) {System.out.println(getName()+": "+i);if(i%10 == 0) {yield();}}}
}

運行結果:

t1到10的倍數切換t2,t2到10的倍數切換t1;


上例子:

package com.zhj.www;public class TestPriority {public static void main(String[] args) {Thread t1 = new Thread(new T1());Thread t2 = new Thread(new T2());t1.setPriority(Thread.NORM_PRIORITY+3);//t1得到的執行時間長t1.start();t2.start();}
}
class T1 implements Runnable{public void run() {for(int i =0;i< 100;i++) {System.out.println("T1: "+ i);}}
}
class T2 implements Runnable{public void run() {for(int i =0;i< 100;i++) {System.out.println("-------T2: "+ i);}}
}
運行一下:

可以發現:t1比t2運行的時間長。

--------------------------------------------------------------------------------------

--------------------------------------------------------------------------------------

額外的栗子:

--------------------------------------------------------------------------------------

TestThread2.java

package com.zhj.www;public class TestThread2 {public static void main(String[] args) {Runner2 r = new Runner2();Thread t1 = new Thread(r);Thread t2 = new Thread(r);t1.start();t2.start();}
}class Runner2 implements Runnable{public void run() {for(int i = 0; i <= 30; i++) {System.out.println("No: "+ i);}}
}

運行一下:

TestThread3.java

package com.zhj.www;public class TestThread3 {public static void main(String[] args) {Runner3  runner3 = new Runner3();Thread thread = new Thread(runner3);thread.start();}
}
class Runner3 implements Runnable {public void run() {for(int i = 0; i<30;i++) {if(i%10 == 0 && i != 0) {try {Thread.sleep(2000);} catch (InterruptedException e) {}}System.out.println("No. " + i);}}
}

當i 是 10的倍數時,會睡眠2s。

運行結果:

TestThread4.java

package com.zhj.www;public class TestThread4 {public static void main(String[] args) {Runner4 r  = new Runner4();Thread t = new Thread(r);t.start();for(int i = 0; i< 100000 ; i++) {if(i%10000 == 0 & i>0) {System.out.println("in thread main i =" + i);}	}System.out.println("Thread mian is over");r.shutDown();}
}class Runner4 implements Runnable{private boolean flag = true;public void run() {int i = 0;while(flag == true) {System.out.println(" " + i++);}}public void shutDown() {flag = false;}
}

主要:怎么讓一個正常執行的線程停止。

run方法結束,線程就結束。

運行結果:


TestThread5.java(關于join方法)

package com.zhj.www;public class TestThread5 {public static void main(String[] args) {Runner5 r = new Runner5();Thread thread = new Thread(r);thread.start();try {thread.join();}catch (InterruptedException e) {}for(int i = 0; i<50;i++) {System.out.println("主線程:"+ i);}}
}
class Runner5 implements Runnable{public void run(){for(int i= 0 ;i<50;i++) {System.out.println("SubThread: " + i);}}
}
運行結果:

TestThread6.java

package com.zhj.www;public class TestThread6 {public static void main(String[] args) {Thread thread = new Runner6();thread.start();for(int i = 0; i<50 ;i++) {System.out.println("MainThread: "+ i);}}
}class Runner6 extends Thread{public void run() {System.out.println(Thread.currentThread().isAlive());for(int i = 0;i<50;i++) {System.out.println("SubThread: " + i);}}
}


----------------------------------------------------------------------------------------------------------------

----------------------------------------------------------------------------------------------------------------

線程同步



自身是一個線程類。

分析內存:


分析完內存,我們運行一下:

package com.zhj.www;public class TestSync implements Runnable{Timer timer  =new Timer();public static void main(String[] args) {TestSync testSync = new TestSync();Thread t1 = new Thread(testSync);Thread t2 = new Thread(testSync);t1.setName("t1");t2.setName("t2");t1.start();t2.start();}public void run() {timer.add(Thread.currentThread().getName());}
}class Timer{private static int num = 0;public void add(String name ) {num++;try {Thread.sleep(1);} catch (InterruptedException e) {}System.out.println(name+",你是第"+num+"個使用timer的線程");}
}

運行一下:

結果為什么是這樣呢?感覺哪里不對。

線程在執行這個方法時,被另一個線程打斷了。寫sleep,是為了

放大這個效果。

怎么解決呢?

在執行的時候,鎖定當前對象。一個執行進入到鎖住區域時,另一個

線程不可打擾。

如下:

public void add(String name ) {synchronized (this) {num++;try {Thread.sleep(1);} catch (InterruptedException e) {}System.out.println(name+",你是第"+num+"個使用timer的線程");}}

互斥鎖。

另外簡便的寫法:

public  synchronized void add(String name ) {//synchronized (this) {num++;try {Thread.sleep(1);} catch (InterruptedException e) {}System.out.println(name+",你是第"+num+"個使用timer的線程");//}}

執行這個方法時,鎖住當前對象。

睡著的時候,依然抱著這把鎖,其他的人如果要執行這個方法必須等他執行完這個方法。



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

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

相關文章

移動互聯網下一步:“深度學習”配合大數據

隨著電子商務不斷深入&#xff0c;百度、騰訊、阿里巴巴的移動互聯網戰略的可比性越來月低&#xff0c;如今百度的移動互聯網的戰略也面臨挑戰&#xff0c;最大的因素在于數據的來源。 對于互聯網的公司最近的動態是什么&#xff1f;這個不是很難的&#xff0c;主要看一下公司的…

windows掛載linux網絡文件系統NFS

ubuntu上安裝配置nfs服務 #apt-get install nfs-kernel-server #mkdir /home/nfs #vim /etc/exports 在文檔的最后一行加入/home/nfs *(rw,sync,no_root_squash,no_subtree_check)&#xff0c;保存退出。 #/etc/init.d/rpcbind restart 重啟rpcbind #/etc/init.d/nfs-kern…

SQL的連接分為三種:內連接、外連接、交叉連接。

先給出兩張表&#xff1a;一、內連接&#xff1a;內連接&#xff08;INNER JOIN&#xff09;&#xff1a;有兩種&#xff0c;顯式的和隱式的&#xff0c;返回連接表中符合連接條件和查詢條件的數據行。&#xff08;所謂的鏈接表就是數據庫在做查詢形成的中間表&#xff09;。1、…

如何在使用摩托羅拉上的RSS閱讀器應用進行一次訂閱

訂閱一個CSDN的RSS為例。 1、打開RSS閱讀器。 2、設置->新增訂閱->手動新增 訂閱URL:輸入http://articles.csdn.net/api/rss.php?tid1000 &#xff08;可以先在PC上打開下該網頁&#xff0c;發現他是一個xml網頁。&#xff09; 訂閱名稱&#xff1a;自己起一個名字&…

RTP與RTCP協議介紹

本文轉自&#xff1a;http://blog.51cto.com/zhangjunhd/25481 1&#xff0e;流媒體( Streaming Media) 1.1流媒體概念 流媒體技術是網絡技術和多媒體技術發展到一定階段的產物。術語流媒體既可以指在網上傳輸連續時基媒體的流式技術,也可以指使用流式技術的連續時基媒體本身…

JSP學習

一、JSP 簡介 什么是Java Server Pages? JSP全稱Java Server Pages&#xff0c;是一種動態網頁開發技術。它使用JSP標簽在HTML網頁中插入Java代碼。標簽通常以<%開頭以%>結束。 JSP是一種Java servlet&#xff0c;主要用于實現Java web應用程序的用戶界面部分。網頁開發…

Java給定一個字符串數組,判斷每個字符出現次數

題目要求&#xff1a;給定一個字符串&#xff0c;判斷每個字符出現多少次&#xff1f; 解決思路&#xff1a;利用Map的特性&#xff1a;即Map集合中如果兩個key&#xff08;鍵&#xff09;值是一樣相同的&#xff0c;那么&#xff0c;后放&#xff08;put&#xff09;入的值會將…

Java-n個人報數

題目&#xff1a; 有n個人圍成一圈&#xff0c;順序排號。從第一個人開始報數&#xff08;從1到3報數&#xff09;&#xff0c;凡報到3的人退出圈子&#xff0c;問最后留下的是原來第幾號的哪一位&#xff1f; 大概思路&#xff1a;假設有3個人&#xff0c;它們圍成一圈&#x…

100個直接可以拿來用的JavaScript實用功能代碼片段

http://www.cnblogs.com/wxydigua/p/3314274.html轉載于:https://www.cnblogs.com/kevinge/p/3316315.html

[轉]JS Cookie 中文亂碼

首先是一個解析cookie的函數&#xff1a; <script type"text/javascript"> function getCookie(name) { var cookies document.cookie.split(";"); for(var i0;i<cookies.length;i) { var cookie cookies[i]; var cookieStr cookie.…

Java線程中關于Synchronized的用法

synchronized是Java中的關鍵字&#xff0c;是一種同步鎖。它修飾的對象有以下幾種&#xff1a; 1. 修飾一個代碼塊&#xff0c;被修飾的代碼塊稱為同步語句塊&#xff0c;其作用的范圍是大括號{}括起來的代碼&#xff0c;作用的對象是調用這個代碼塊的對象&#xff1b; 2. 修飾…

cmd命令行設置環境變量

http://blog.sciencenet.cn/blog-51026-566742.html 1、查看當前所有可用的環境變量&#xff1a;輸入 set 即可查看。 2、查看某個環境變量&#xff1a;輸入 “set 變量名”即可&#xff0c;比如想查看path變量的值&#xff0c;即輸入 set path。 3、修改環境變量 &#xff1a;…

Java線程之多線程與多進程(1)——以操作系統的角度述說線程與進程

任務調度 線程是什么&#xff1f;要理解這個概念&#xff0c;須要先了解一下操作系統的一些相關概念。大部分操作系統(如Windows、Linux)的任務調度是采用時間片輪轉的搶占式調度方式&#xff0c;也就是說一個任務執行一小段時間后強制暫停去執行下一個任務&#xff0c;每個任務…

用 PS 調整服務器時間

用 PS 調整服務器時間 Powershell 有一個命令用來調整計算機的時間&#xff0c; Set-Date -Adjust&#xff0c;但是&#xff0c;只能調整本地時間&#xff0c;不能調整遠程的計算機時間。 function AdjustDCTime ( $Server, $addTime ){ $Svr Get-WmiObject Win32_Operatin…

Java線程之多線程與多進程(2)——線程優先級與線程安全

線程優先級 現在主流操作系統(如Windows、Linux、Mac OS X)的任務調度除了具有前面提到的時間片輪轉的特點外&#xff0c;還有優先級調度(Priority Schedule)的特點。優先級調度決定了線程按照什么順序輪流執行&#xff0c;在具有優先級調度的系統中&#xff0c;線程擁有各自的…

mahout貝葉斯算法開發思路(拓展篇)1

首先說明一點&#xff0c;此篇blog解決的問題是就下面的數據如何應用mahout中的貝葉斯算法&#xff1f;&#xff08;這個問題是在上篇&#xff08;。。。完結篇&#xff09;blog最后留的問題&#xff0c;如果想直接使用該工具&#xff0c;可以在mahout貝葉斯算法拓展下載&#…

Java線程之多線程與多進程(3)——Java中的多線程

單線程 任何程序至少有一個線程&#xff0c;即使你沒有主動地創建線程&#xff0c;程序從一開始執行就有一個默認的線程&#xff0c;被稱為主線程&#xff0c;只有一個線程的程序稱為單線程程序。如下面這一簡單的代碼&#xff0c;沒有顯示地創建一個線程&#xff0c;程序從mai…

幾種常用控件的使用方法

1.UIActivityIndicatorView的使用 UIActivityIndicatorView *activity[[[UIActivityIndicatorViewalloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleGray]autorelease]; z [activity setFrame:CGRectMake(150,150, 50, 50)]; [self.window addSubview:activ…

Java-正則表達式

什么是正則表達式&#xff1f; 正則表達式(Regular Expression)就是用某種模式去匹配一類字符串的公式。如你要在一篇文章中查找第一個字是“李”最后一個字是“建”的三個字的姓名&#xff0c;即“李*建”&#xff1b;那么“李*建”就是公式&#xff0c;也稱作模式(Pattern)&a…

tab標簽的另一種寫法

<div class"good"><ul><li><span>歌曲精選</span></li><li class"other"><span>MV精選</span></li></ul><div class"music_good"><p><span>丁當</span…