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

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 人文社科 > 生活经验 >内容正文

生活经验

java线程触发_java线程

發(fā)布時(shí)間:2023/11/27 生活经验 34 豆豆
生活随笔 收集整理的這篇文章主要介紹了 java线程触发_java线程 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

線程.

狀態(tài)

新建狀態(tài)(New):

當(dāng)用 new 操作符創(chuàng)建一個(gè)線程時(shí), 例如 new Thread(r),線程還沒有開始運(yùn)行,此時(shí)

線程處在新建狀態(tài)。 當(dāng)一個(gè)線程處于新生狀態(tài)時(shí),程序還沒有開始運(yùn)行線程中的代碼

就緒狀態(tài)(Runnable)

一個(gè)新創(chuàng)建的線程并不自動(dòng)開始運(yùn)行,要執(zhí)行線程,必須調(diào)用線程的 start()方法。當(dāng)線

程對(duì)象調(diào)用 start()方法即啟動(dòng)了線程,start()方法創(chuàng)建線程運(yùn)行的系統(tǒng)資源,并調(diào)度線程運(yùn)行

run()方法。當(dāng) start()方法返回后,線程就處于就緒狀態(tài)。

處于就緒狀態(tài)的線程并不一定立即運(yùn)行 run()方法,線程還必須同其他線程競(jìng)爭(zhēng) CPU 時(shí)

間,只有獲得 CPU 時(shí)間才可以運(yùn)行線程。因?yàn)樵趩?CPU 的計(jì)算機(jī)系統(tǒng)中,不可能同時(shí)運(yùn)行

多個(gè)線程,一個(gè)時(shí)刻僅有一個(gè)線程處于運(yùn)行狀態(tài)。因此此時(shí)可能有多個(gè)線程處于就緒狀態(tài)。

對(duì)多個(gè)處于就緒狀態(tài)的線程是由 Java 運(yùn)行時(shí)系統(tǒng)的線程調(diào)度程序(thread scheduler)來調(diào)度

的。

運(yùn)行狀態(tài)(Running)

當(dāng)線程獲得 CPU 時(shí)間后,它才進(jìn)入運(yùn)行狀態(tài),真正開始執(zhí)行 run()方法.

阻塞狀態(tài)(Blocked)

線程運(yùn)行過程中,可能由于各種原因進(jìn)入阻塞狀態(tài):

1>線程通過調(diào)用 sleep 方法進(jìn)入睡眠狀態(tài);

2>線程調(diào)用一個(gè)在 I/O 上被阻塞的操作,即該操作在輸入輸出操作完成之前不會(huì)返回

到它的調(diào)用者;

3>線程試圖得到一個(gè)鎖,而該鎖正被其他線程持有;

4>線程在等待某個(gè)觸發(fā)條件;

......

所謂阻塞狀態(tài)是正在運(yùn)行的線程沒有運(yùn)行結(jié)束,暫時(shí)讓出 CPU,這時(shí)其他處于就緒狀

態(tài)的線程就可以獲得 CPU 時(shí)間,進(jìn)入運(yùn)行狀態(tài)。

死亡狀態(tài)(Dead)

有兩個(gè)原因會(huì)導(dǎo)致線程死亡:

run 方法正常退出而自然死亡,

一個(gè)未捕獲的異常終止了 run 方法而使線程猝死。

為了確定線程在當(dāng)前是否存活著(就是要么是可運(yùn)行的,要么是被阻塞了),需要使

用 isAlive 方法。如果是可運(yùn)行或被阻塞,這個(gè)方法返回 true; 如果線程仍舊是 new 狀態(tài)

且不是可運(yùn)行的, 或者線程死亡了,則返回 false

新建線程的方法:

1.繼承Thread類實(shí)現(xiàn)多線程

run()為線程類的核心方法,相當(dāng)于主線程的main方法,是每個(gè)線程的入口

一個(gè)線程調(diào)用 兩次start()方法將會(huì)拋出線程狀態(tài)異常,也就是的start()只可以被調(diào)用一次

class Thread1 extends Thread{

@Override

public void run() {

//迭代 循環(huán)

for (int i = 0; i < 10; i++) {

System.out.println(Thread.currentThread().getName()+"__"+i);

}

}

}

public class ThreadTest {

public static void main(String[] args) {

System.out.println("main start: "+Thread.currentThread().getName());

for (int i = 0; i < 10; i++) {

Thread1 thread1 =new Thread1();

thread1.start();//多個(gè)跑道 并行

}

//main 不等了

System.out.println(" main end ");

}

}

2通過Runnable接口創(chuàng)建線程類

定義runnable接口的實(shí)現(xiàn)類,并重寫該接口的run()方法,該run()方法的方法體同樣是該線程的線程執(zhí)行體。

創(chuàng)建 Runnable實(shí)現(xiàn)類的實(shí)例,并以此實(shí)例作為Thread的target來創(chuàng)建Thread對(duì)象,該Thread對(duì)象才是真正的線程對(duì)象。

調(diào)用線程對(duì)象的start()方法來啟動(dòng)該線程。

public class RunnableThreadTest implements Runnable {

@Override

public void run() {

for (int i = 0; i < 10; i++) {

System.out.println(Thread.currentThread().getName() + "__" + i);

}

}

public static void main(String[] args) {

System.out.println("main start: "+Thread.currentThread().getName());

for (int i = 0; i < 5; i++) {

RunnableThreadTest runnableThreadTest = new RunnableThreadTest();

new Thread(runnableThreadTest,"線程"+i).start();

}

}

}

通過Callable和Future創(chuàng)建線程

創(chuàng)建Callable接口的實(shí)現(xiàn)類,并實(shí)現(xiàn)call()方法,該call()方法將作為線程執(zhí)行體,并且有返回值。

public interface Callable

{

V call() throws Exception;

}

創(chuàng)建Callable實(shí)現(xiàn)類的實(shí)例,使用FutureTask類來包裝Callable對(duì)象,該FutureTask對(duì)象封裝了該Callable對(duì)象的call()方法的返回值。(FutureTask是一個(gè)包裝器,它通過接受Callable來創(chuàng)建,它同時(shí)實(shí)現(xiàn)了Future和Runnable接口。)

使用FutureTask對(duì)象作為Thread對(duì)象的target創(chuàng)建并啟動(dòng)新線程。

調(diào)用FutureTask對(duì)象的get()方法來獲得子線程執(zhí)行結(jié)束后的返回值

public class CallableThreadTest implements Callable

{

public static void main(String[] args)

{

CallableThreadTest ctt = new CallableThreadTest();

FutureTask ft = new FutureTask<>(ctt);

for(int i = 0;i < 100;i++)

{

log.info(Thread.currentThread().getName()+" 的循環(huán)變量i的值"+i);

if(i==20)

{

new Thread(ft,"有返回值的線程").start();

}

}

try

{

log.info("子線程的返回值:"+ft.get());

} catch (InterruptedException e)

{

e.printStackTrace();

} catch (ExecutionException e)

{

e.printStackTrace();

}

}

@Override

public Integer call() throws Exception

{

int i = 0;

for(;i<100;i++)

{

log.info(Thread.currentThread().getName()+" "+i);

}

return i;

}

}

并行參數(shù)問題的解決

ThreadLocal (線程本地變量) map

新建ThreadLocal并重寫initialValue() 重寫initialValue 方法 否者對(duì)象為空

調(diào)用方法(ThreadLocal定義的變量名)threadLocal.get();

package com.testfan.thread;

import java.util.HashMap;

import java.util.Map;

public class ThreadLocalMapTest {

static ThreadLocal> threadLocal = new ThreadLocal>(){

@Override

protected Map initialValue() {

return new HashMap();

}

};

public static void main(String[] args) {

threadLocal.get().put("1","11");

dosomethings();

new Thread(new Runnable() {

@Override

public void run() {

threadLocal.get().put("1","22");

dosomethings();

}

}).start();

new Thread(new Runnable() {

@Override

public void run() {

threadLocal.get().put("1","33");

dosomethings();

}

}).start();

}

private static void dosomethings() {

System.out.println(Thread.currentThread().getName() + " " +threadLocal.get());

}

}

線程等待問題

線程等待 join

for (int i = 0; i < 10; i++) {

Thread1 thread1 =new Thread1();

thread1.start();//多個(gè)跑道 并行

try {

thread1.join();//線程等待

} catch (InterruptedException e) {

// TODO Auto-generated catch block

e.printStackTrace();

}

sleep

public static void main(String[] args) {

System.out.println("main start: "+Thread.currentThread().getName());

for (int i = 0; i < 10; i++) {

Thread1 thread1 =new Thread1();

thread1.start();//多個(gè)跑道 并行

try {

thread1.sleep(1);;//線程等待

} catch (InterruptedException e) {

// TODO Auto-generated catch block

e.printStackTrace();

}

線程計(jì)數(shù)器

public class ThreadDemo2 {

public static void main(String[] args) throws InterruptedException {

final CountDownLatch latch= new CountDownLatch(5);//使用java并發(fā)庫(kù)concurrent

//啟用5個(gè)線程

for(int i=1;i<=5;i++){

new Thread(new Runnable(){

public void run(){

try {

Thread.sleep(1000);

} catch (Exception e) {

e.printStackTrace();

}

System.out.println("子線程執(zhí)行!");

latch.countDown();//讓latch中的數(shù)值減一

}

}).start();

}

//主線程

latch.await();//阻塞當(dāng)前線程直到latch中數(shù)值為零才執(zhí)行

System.out.println("主線程執(zhí)行!");

}

}

countDownLatch不可能重新初始化或者修改CountDownLatch對(duì)象內(nèi)部計(jì)數(shù)器的值,一個(gè)線程調(diào)用countdown方法happen-before另外一個(gè)線程調(diào)用await方法

線程池優(yōu)化

為什么用線程池:

服務(wù)器應(yīng)用程序中經(jīng)常出現(xiàn)的情況是:單個(gè)任務(wù)處理的時(shí)間很短而請(qǐng)求的數(shù)目卻是巨大的。

為每個(gè)請(qǐng)求創(chuàng)建一個(gè)新線程的開銷很大;為每個(gè)請(qǐng)求創(chuàng)建新線程的服務(wù)器在創(chuàng)建和銷毀線程上花費(fèi)的時(shí)間和消耗的系統(tǒng)資源要比花在處理實(shí)際的用戶請(qǐng)求的時(shí)間和資源更多。

線程池為線程生命周期開銷問題和資源不足問題提供了解決方案

好處:

在請(qǐng)求到達(dá)時(shí)線程已經(jīng)存在,所以無意中也消除了線程創(chuàng)建所帶來的延遲。這樣,就可以立即為請(qǐng)求服務(wù),使應(yīng)用程序響應(yīng)更快。而且,通過適當(dāng)?shù)卣{(diào)整線程池中的線程數(shù)目,也就是當(dāng)請(qǐng)求的數(shù)目超過某個(gè)閾值時(shí),就強(qiáng)制其它任何新到的請(qǐng)求一直等待,直到獲得一個(gè)線程來處理為止,從而可以防止資源不足。

線程池的幾種方法:

https://www.cnblogs.com/aaron911/p/6213808.html

第一種:定時(shí)任務(wù)(jenkines的定時(shí)任務(wù))

ScheduledExecutorService scheduledThreadPool = Executors.newScheduledThreadPool(5);

實(shí)例:

ScheduledExecutorService scheduledThreadPool = Executors.newScheduledThreadPool(5);

scheduledThreadPool.scheduleAtFixedRate(new Runnable() {

@Override

public void run() {

System.out.println("111111");

}

},0,1,TimeUnit.SECONDS);//0代表延時(shí)多久 1代表多久執(zhí)行一次,TimeUnit.SECONDS代表時(shí)間單位

第二種:

//可以最大開65536, 短任務(wù)

ExecutorService cachedThreadPool = Executors.newCachedThreadPool();

實(shí)例:

for (int i = 0; i < 100000; i++) {

final int index = i;

//放了十個(gè)線程

cachedThreadPool.execute(new Runnable() {

public void run() {

System.out.println(index+Thread.currentThread().getName());

}

});

}

fixedThreadPool.shutdown();

第三種:

//按照固定的數(shù)目

ExecutorService fixedThreadPool = Executors.newFixedThreadPool(3);//一次運(yùn)行3個(gè)

實(shí)例:

for (int i = 0; i < 100; i++) {

final int index = i;

//放了十個(gè)線程

fixedThreadPool.execute(new Runnable() {

public void run() {

System.out.println(index+Thread.currentThread().getName());

}

});

}

fixedThreadPool.shutdown();

第四種:

//默認(rèn)一個(gè)

ExecutorService singleThreadExecutor = Executors.newSingleThreadExecutor();

實(shí)例:

for (int i = 0; i < 100; i++) {

final int index = i;

//放了十個(gè)線程

singleThreadExecutor.execute(new Runnable() {

public void run() {

System.out.println(index+Thread.currentThread().getName());

}

});

}

fixedThreadPool.shutdown();

總結(jié)

以上是生活随笔為你收集整理的java线程触发_java线程的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。