java 多線程的三種構(gòu)建方法

創(chuàng)新互聯(lián)主營(yíng)秦都網(wǎng)站建設(shè)的網(wǎng)絡(luò)公司,主營(yíng)網(wǎng)站建設(shè)方案,成都App定制開發(fā),秦都h5小程序開發(fā)搭建,秦都網(wǎng)站營(yíng)銷推廣歡迎秦都等地區(qū)企業(yè)咨詢
繼承Thread類創(chuàng)建線程類
public class Thread extends Object implements Runnable
public class FirstThread extends Thread {
public void run(){
for(int i=0;i<100;i++){
/*
* Thread類已經(jīng)繼承了Object
* Object類創(chuàng)建了name選項(xiàng) 并且有其getName(),setName()方法
* 在繼承Thread的類里面使用時(shí)只需要用this引用
*/
System.out.println(this.getName()+" "+i);
}
}
public static void main(String[] args) {
for(int i=0;i<100;i++){
System.out.println(Thread.currentThread().getName()+" "+i);
if(i==20){
new FirstThread().start();
new FirstThread().start();
}
}
}
}
Thread類已經(jīng)繼承了Object
Object類創(chuàng)建了name選項(xiàng) 并且有其getName(),setName()方法
在繼承Thread的類里面使用時(shí)只需要用this引用
上面兩個(gè)副線程和主線程隨機(jī)切換,又因?yàn)槭褂玫氖抢^承Thread的類所以兩個(gè)副線程不能共享資源
start()方法調(diào)用后并不是立即執(zhí)行多線程代碼,而是使得該線程編程可運(yùn)行狀態(tài),什么時(shí)候運(yùn)行是由操作系統(tǒng)決定的
實(shí)現(xiàn)Runnable接口創(chuàng)建線程類
public Thread() public Thread(Runnable target) public Thread(Runnable target,String name)
public class SecondThread implements Runnable {
public void run(){
for(int i=0;i<100;i++){
System.out.println(Thread.currentThread().getName()+" "+i);
}
}
public static void main(String[] args) {
for(int i=0;i<100;i++){
System.out.println(Thread.currentThread().getName()+" "+i);
if(i==20){
SecondThread st=new SecondThread();
//通過(guò)new Thread(target,name)創(chuàng)建線程
new Thread(st,"新線程1").start();
new Thread(st,"新線程2").start();
}
}
}
}
上面的結(jié)果是兩個(gè)副線程和主線程隨機(jī)切換,但是并沒(méi)有共享資源,因?yàn)樗麄兏緵](méi)有能用來(lái)共享的資源。
start()方法調(diào)用后并不是立即執(zhí)行多線程代碼,而是使得該線程編程可運(yùn)行狀態(tài),什么時(shí)候運(yùn)行是由操作系統(tǒng)決定的
繼承Thread類和創(chuàng)建Runnable接口的共享資源詳解
在只有可以用來(lái)共享的資源時(shí)候,也就是同用一個(gè)實(shí)例化對(duì)象。兩個(gè)創(chuàng)建方式在共享資源時(shí)才會(huì)有所區(qū)別,否則它們都不會(huì)共享資源共享資源通常用private static 修飾符來(lái)修飾。
class Thread1 extends Thread{
private int count=5;
private String name;
public Thread1(String name) {
this.name=name;
}
public void run() {
for (int i = 0; i < 5; i++) {
System.out.println(name + "運(yùn)行 count= " + count--);
try {
sleep((int) Math.random() * 10);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
public class Main {
public static void main(String[] args) {
Thread1 mTh2=new Thread1("A");
Thread1 mTh3=new Thread1("B");
mTh2.start();
mTh3.start();
}
}
B運(yùn)行 count= 5 A運(yùn)行 count= 5 B運(yùn)行 count= 4 B運(yùn)行 count= 3 B運(yùn)行 count= 2 B運(yùn)行 count= 1 A運(yùn)行 count= 4 A運(yùn)行 count= 3 A運(yùn)行 count= 2 A運(yùn)行 count= 1
正是因?yàn)橛辛藀rivate int count=5;一句才有了共享資源,但這是繼承Thread類的子類,并不能共享資源
class Thread2 implements Runnable{
private int count=15;
public void run() {
for (int i = 0; i < 5; i++) {
System.out.println(Thread.currentThread().getName() + "運(yùn)行 count= " + count--);
try {
Thread.sleep((int) Math.random() * 10);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
public class Main {
public static void main(String[] args) {
Thread2 my = new Thread2();
new Thread(my, "C").start();//同一個(gè)mt,但是在Thread中就不可以,如果用同一個(gè)實(shí)例化對(duì)象mt,就會(huì)出現(xiàn)異常
new Thread(my, "D").start();
new Thread(my, "E").start();
}
}
C運(yùn)行 count= 15 D運(yùn)行 count= 14 E運(yùn)行 count= 13 D運(yùn)行 count= 12 D運(yùn)行 count= 10 D運(yùn)行 count= 9 D運(yùn)行 count= 8 C運(yùn)行 count= 11 E運(yùn)行 count= 12 C運(yùn)行 count= 7 E運(yùn)行 count= 6 C運(yùn)行 count= 5 E運(yùn)行 count= 4 C運(yùn)行 count= 3 E運(yùn)行 count= 2
同樣的正是因?yàn)橛辛藀rivate int count=15這個(gè)共同的實(shí)例化對(duì)象,實(shí)現(xiàn)Runnable的類才可以共享資源
那么為什么繼承Thread類的子類實(shí)現(xiàn)Runable接口的類在共享資源時(shí)有區(qū)別呢?
因?yàn)镴ava中只能支持單繼承,單繼承特點(diǎn)意味著只能有一個(gè)子類去繼承 而Runnabl接口后可以跟好多類,便可以進(jìn)行多個(gè)線程共享一個(gè)資源的操作
使用Callable和Future創(chuàng)建線程
Callable怎么看起來(lái)都像Runnable接口的增強(qiáng)版,Callable有一個(gè)call()方法相當(dāng)于Runnable的run()方法,但是功能卻更加強(qiáng)大:
call()方法可以有返回值
call()方法可以聲明拋出異常
Callable接口有泛型限制,Callable接口里的泛型形參類型與call()方法的返回值類型相同。 而且Callable接口是函數(shù)式接口,因此可使用Lambda表達(dá)式創(chuàng)建Callable對(duì)象 Runnable接口也是函數(shù)式接口,因此也可以使用Lambda表達(dá)式創(chuàng)建Runnable對(duì)象
public class ThirdThread implements Callable<Integer> {
public Integer call(){
int i=0;
for(;i<100;i++){
System.out.println(Thread.currentThread().getName()+" "+i);
}
return i;
}
public static void main(String[] args){
ThirdThread tt=new ThirdThread();
FutureTask<Integer> task=new FutureTask<>(tt);
Thread t=new Thread(task,"有返回值的線程");
for(int i=0;i<100;i++){
System.out.println(Thread.currentThread().getName()+" "+i);
if(i==20){
t.start();
}
}
try{
System.out.println("返回值是:"+task.get());
}catch(Exception e){
e.printStackTrace();
}
}
}
使用Lambda表達(dá)式的Callable和Future創(chuàng)建的線程
public class ThirdThread{
public static void main(String[] args){
ThirdThread tt=new ThirdThread();
//先使用Lambda表達(dá)式創(chuàng)建Callable<Integer>對(duì)象
//使用FutureTask封裝Callable對(duì)象
FutureTask<Integer> task=new FutureTask<Integer>((Callable<Integer>)()->{
int i=0;
for(;i<100;i++){
System.out.println(Thread.currentThread().getName()+"的循環(huán)變量i的值:"+i);
}
return i;
});
for(int i=0;i<100;i++){
System.out.println(Thread.currentThread().getName()+"的循環(huán)變量i的值:"+i);
if(i==20){
new Thread(task,"有返回值的線程").start();
}
}
try{
System.out.println("子線程的返回值"+task.get());
}catch(Exception e){
e.printStackTrace();
}
}
}
如有疑問(wèn)請(qǐng)留言或者到本站社區(qū)交流討論,感謝閱讀,希望能幫助到大家,謝謝大家對(duì)本站的支持!
網(wǎng)站題目:java 多線程的三種構(gòu)建方法
本文網(wǎng)址:http://www.jbt999.com/article44/pdgihe.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供網(wǎng)站制作、面包屑導(dǎo)航、做網(wǎng)站、動(dòng)態(tài)網(wǎng)站、微信公眾號(hào)、網(wǎng)站改版
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:[email protected]。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來(lái)源: 創(chuàng)新互聯(lián)