中文亚洲精品无码_熟女乱子伦免费_人人超碰人人爱国产_亚洲熟妇女综合网

當(dāng)前位置: 首頁(yè) > news >正文

成都網(wǎng)站建設(shè)前十注冊(cè)網(wǎng)站流程

成都網(wǎng)站建設(shè)前十,注冊(cè)網(wǎng)站流程,到做任務(wù)的網(wǎng)站上面推廣粉象生,臺(tái)灣做電商網(wǎng)站有哪些目錄 創(chuàng)建線程 方法一:繼承Thread類來(lái)創(chuàng)建一個(gè)線程類 方法二:實(shí)現(xiàn)Runnable,重寫run 線程等待 獲取當(dāng)前線程引用 休眠當(dāng)前線程 線程的狀態(tài) synchronized synchronized的特性 1、互斥 2、刷新內(nèi)存 死鎖 死鎖的四個(gè)必要條件 避免死…

目錄

創(chuàng)建線程

方法一:繼承Thread類來(lái)創(chuàng)建一個(gè)線程類

方法二:實(shí)現(xiàn)Runnable,重寫run

線程等待

獲取當(dāng)前線程引用

休眠當(dāng)前線程

線程的狀態(tài)

synchronized

synchronized的特性

1、互斥

2、刷新內(nèi)存

死鎖

死鎖的四個(gè)必要條件

避免死鎖

volatile關(guān)鍵字

wait方法

notify方法

定時(shí)器

線程池?

線程池的創(chuàng)建

往線程池里添加任務(wù)


創(chuàng)建線程

方法一:繼承Thread類來(lái)創(chuàng)建一個(gè)線程類

class MyThread extends Thread{
??? @Override
??? public void run() {
??????? while(true)
??????? {
??????????? System.out.println("1111");
??????? }
??? }
}

public class Main {

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

? ? ? ? //創(chuàng)建Mythread類的實(shí)例
??????? MyThread myThread=new MyThread();

? ? ? ? //調(diào)用start方法啟動(dòng)線程
??????? myThread.start();
??? }
}?

繼承Thread,使用匿名內(nèi)部類

Thread t =new Thread(){
??? @Override
??? public void run() {
??????? System.out.println("111");
??? }
};
t.start();

方法二:實(shí)現(xiàn)Runnable,重寫run

class MyRunnable implements? Runnable{
??? @Override
??? public void run() {
??????? while (true){
??????????? System.out.println("hello thread");
??????????? try {
??????????????? Thread.sleep(1000);
??????????? } catch (InterruptedException e) {
??????????????? throw new RuntimeException(e);
??????????? }
??????? }
??? }
}
public class Main {

??? public static void main(String[] args) {
??????? Runnable runnable=new MyRunnable();
??????? Thread t =new Thread(runnable);
??????? t.start();
??? }
}

使用Runnable和繼承Thread方法的區(qū)別在于:解耦合

TIPS

.start 和 .run方法的區(qū)別:

.run代碼中不會(huì)創(chuàng)建出新的線程,只有一個(gè)主線程,這個(gè)主線程里面只能依次執(zhí)行循環(huán),執(zhí)行完一個(gè)循環(huán)再執(zhí)行另一個(gè)

我們可以使用IDEA或者jconsole來(lái)觀察進(jìn)程里多線程的情況

jconsole是jdk自帶的工具,我們?cè)趈dk的bin目錄里可以找到?

在啟動(dòng)jconsole前,確保idea程序已經(jīng)跑起來(lái)了,如下會(huì)列出當(dāng)前機(jī)器上運(yùn)行的所有java進(jìn)程

Thread-0就是我們新建的線程

?如果要更明顯的找到新線程,我們?cè)趧?chuàng)建線程的時(shí)候,給它設(shè)置一下名字

Thread t =new Thread(()->{
??? while(true){
??????? System.out.println("hello");
??? }
},"這是新線程名字");
t.start();

線程屬性

屬性獲取方法
IDgetid()
名稱

getName()

狀態(tài)getState()
優(yōu)先級(jí)getPriority()
是否后臺(tái)線程isDaemon()
是否存活isAlive()
是否被中斷isinterrupted()
  • 這里的id是java分配的,不是系統(tǒng)api提供的
  • 后臺(tái)線程不結(jié)束,不影響整個(gè)進(jìn)程結(jié)束,設(shè)置后臺(tái)線程 t.setDaemon(true)
  • 前臺(tái)線程沒有執(zhí)行結(jié)束,整個(gè)進(jìn)程是一定不會(huì)結(jié)束的
  • isAlive判定內(nèi)核線程是不是已經(jīng)沒了,回調(diào)方法執(zhí)行完畢,線程就沒了,但是Thread對(duì)象可能還在。

lambda表達(dá)式有一個(gè)語(yǔ)法規(guī)則,變量捕獲,是可以自動(dòng)捕獲到上層作用域中涉及到的局部變量,所謂變量捕獲,就是讓lambda表達(dá)式,把當(dāng)前作用域中的變量在lambda內(nèi)部復(fù)制了一份

只能捕獲一個(gè)final或者實(shí)際上是final的常量(變量沒有使用final,但是沒有進(jìn)行修改)

在java中并不能像C++一樣,直接中斷一個(gè)線程,只能讓線程任務(wù)做的快一點(diǎn),依靠標(biāo)志位來(lái)決定,具體示例如下:

Thread t =new Thread(()->{
??? while(!Thread.currentThread().isInterrupted()){
??????? System.out.println("hello");
??? }
},"這是新線程名字");
t.start();
System.out.println("讓t線程結(jié)束");
t.interrupt();

設(shè)置標(biāo)志位的相關(guān)方法

方法說(shuō)明

public void interrupt()

中斷對(duì)象關(guān)聯(lián)的線程,如果線程正在阻塞,則以異常方式通知,否則設(shè)置標(biāo)志位
publi static boolean interrupted()判斷當(dāng)前線程的中斷標(biāo)志位是否設(shè)置,調(diào)用后清除標(biāo)志位
public boolean isinterrupted()判斷對(duì)象關(guān)聯(lián)的線程的標(biāo)志位是否設(shè)置,調(diào)用后不清除標(biāo)志位

線程等待

讓一個(gè)線程等待另一個(gè)線程執(zhí)行結(jié)束,再繼續(xù)執(zhí)行,本質(zhì)就是控制線程結(jié)束的順序

join線程等待核心方法

方法說(shuō)明
public void join()等待線程結(jié)束
public void join(long millis)等待線程結(jié)束,最多等millis毫秒
public void join(long millis,int nanos)等待時(shí)間精度更高

主線程中,調(diào)用t.join() 此時(shí)就是主線程等待t線程先結(jié)束

Thread t =new Thread(()->{
??? for(int i=0;i<5;i++)
??? {
??????? System.out.println("t線程工作");
??? }
},"這是新線程名字");
t.start();
System.out.println("主線程開始等待");
t.join();
System.out.println("主線程等待結(jié)束");

一旦調(diào)用join,主線程就會(huì)發(fā)生阻塞,一直阻塞到t執(zhí)行完畢了(沒有設(shè)置等待時(shí)間的話),join才會(huì)解除阻塞,主線程才會(huì)繼續(xù)執(zhí)行?

獲取當(dāng)前線程引用

方法說(shuō)明
public static Thread currentThread()返回當(dāng)前線程對(duì)象的引用

休眠當(dāng)前線程

方法說(shuō)明
public static void sleep(long millis)休眠當(dāng)前線程millis毫秒
public static void sleep(long millis,int nanos)更高精度

線程的狀態(tài)

JAVA中有六個(gè)線程狀態(tài):

  • NEW:安排了任務(wù),還未開始行動(dòng)
  • RUNNABLE:可工作的,又可以分為正在工作中和即將開始工作(也就是就緒狀態(tài))
  • BLOCKED:排隊(duì)等待,由于鎖競(jìng)爭(zhēng)導(dǎo)致的阻塞
  • WAITING:排隊(duì)等待,由wait這種不固定時(shí)間的方式產(chǎn)生的阻塞
  • TIMED_WAITING:排隊(duì)等待,由于sleep這種固定時(shí)間的方式產(chǎn)生的阻塞
  • TERMINATED:工作完成了,Thread對(duì)象還在,內(nèi)核中的線程已經(jīng)沒了

獲取線程狀態(tài)可以通過getState方法,如下:

System.out.println(t.getState());
t.start();
t.join();
System.out.println(t.getState());

synchronized

因?yàn)榫€程的調(diào)度順序是不確定的,這會(huì)導(dǎo)致線程不安全的情況,因此我們需要引入鎖,再Java的一個(gè)對(duì)象對(duì)應(yīng)的內(nèi)存空間中,除了自己定義的一些屬性之外,還有一些自帶的屬性,對(duì)象頭,對(duì)象頭中,其中就有屬性表示當(dāng)前對(duì)象是否已經(jīng)加鎖

synchronized的特性

1、互斥

synchronized會(huì)起到互斥效果,某個(gè)線程執(zhí)行到某個(gè)對(duì)象的synchronized中時(shí),其他線程如果也執(zhí)行到同一個(gè)對(duì)象,synchronized就會(huì)阻塞等待。

  • 進(jìn)入synchronized修飾的代碼塊,相當(dāng)于加鎖
  • 退出synchronized修飾的代碼塊,相當(dāng)于解鎖

synchronized除了修飾代碼塊之外,還可以修飾一個(gè)實(shí)例方法,或者修飾一個(gè)靜態(tài)方法

對(duì)于普通方法,有兩種寫法:

第一種:

synchronized public void increase()
{
??? count++;
}

第二種:

public void increase()
{
??? synchronized (this)
??? {
??????? count++;
??? }
}

這兩種方法是一樣的,第一種可以看成第二種的簡(jiǎn)寫?。

如果是修飾靜態(tài)方法,相當(dāng)于是針對(duì)類對(duì)象加鎖

class Counter{
??? public int count;

? ? //第一種方法
??? synchronized public static void increase()
??? {

??? }

? ? //第二種方法
??? public static void increase()
??? {
??????? synchronized (Counter.class)
??????? {
??????????? count++;
??????? }
??? }
}

?兩種方法也是等價(jià)的。

2、刷新內(nèi)存

synchronized的工作過程:

  1. 獲得互斥鎖
  2. 從主內(nèi)存拷貝變量到最新副本工作的內(nèi)存
  3. 執(zhí)行代碼
  4. 將更改后的共享變量的值刷新到主內(nèi)存
  5. 釋放互斥鎖

當(dāng)出現(xiàn)如下代碼:

synchronized (locker)

?{
???????synchronized (locker){

? ? ? ? ……

????????}
?}

3、可重入

???????第一次加鎖,假設(shè)能夠加鎖成功,此時(shí)的locker就屬于是“被鎖定的”狀態(tài),進(jìn)行第二次加鎖,很明顯,locker已經(jīng)是鎖定狀態(tài)了,第二次加鎖操作,原則上是應(yīng)該要“阻塞等待”的,應(yīng)該要等待到鎖被釋放,才能加鎖成功的,?但是實(shí)際上,一旦第二次加鎖的時(shí)候阻塞了,就會(huì)出現(xiàn)死鎖情況。

????????因此synchronized的可重入性,也就是記錄當(dāng)前持有鎖的線程,如果是持有鎖的線程再進(jìn)行加鎖,則允許加鎖。但是釋放鎖是要到最外層結(jié)束才釋放,這里使用了引用計(jì)數(shù),鎖對(duì)象中,不僅要記錄誰(shuí)拿到了鎖,還要記錄,鎖被加了幾次,每加鎖一次,計(jì)數(shù)器就+1,每解鎖一次,計(jì)數(shù)器就-1,直到0,才真正釋放鎖

死鎖

死鎖的四個(gè)必要條件

  1. 互斥使用(鎖的基本特性):當(dāng)一個(gè)線程持有一把鎖之后,另一個(gè)線程也想獲取到鎖,就需要阻塞等待
  2. 不可搶占(鎖的基本特性):當(dāng)鎖已經(jīng)被線程1拿到之后,線程2只能等線程1主動(dòng)釋放,不能強(qiáng)行搶占過來(lái)
  3. 請(qǐng)求保持(代碼結(jié)構(gòu)):一個(gè)線程嘗試獲取多把鎖,先拿到鎖1,再拿鎖2的時(shí)候,鎖1不釋放
  4. 循環(huán)等待/環(huán)路等待:等待的依賴關(guān)系,形成環(huán)

避免死鎖

解決死鎖,破壞上面三、四條件即可

  • 對(duì)于3來(lái)說(shuō),調(diào)整代碼結(jié)構(gòu),避免寫“鎖嵌套”邏輯
  • 對(duì)于4來(lái)說(shuō),可以約定加鎖順序,就可以避免循環(huán)等待,針對(duì)鎖進(jìn)行編號(hào),比如約定加多把鎖的時(shí)候,先加編號(hào)小的鎖,后加編號(hào)大的鎖

volatile關(guān)鍵字

1、保證內(nèi)存可見性

????????用volatile修飾的變量,每次都從內(nèi)存中讀取值,而不會(huì)因?yàn)榫幾g器優(yōu)化,將常訪問未修改的變量值讀取到寄存器,內(nèi)存中對(duì)應(yīng)變量值修改后,程序還是訪問的寄存器(java中叫做工作內(nèi)存)的值,從而導(dǎo)致“內(nèi)存可見性”問題(也是線程安全的問題)。

????????關(guān)于內(nèi)存可見性,還涉及到一個(gè)關(guān)鍵概念,JMM(Java內(nèi)存模型)

2、禁止指令重排序

TIPS

????????volatile和synchronized都能對(duì)線程安全起到一定的積極作用,但是volatile不能保證原子性,而synchronized保證原子性,synchronized也能保證內(nèi)存可見性。

wait方法

wait做的事情:

  • 使當(dāng)前執(zhí)行代碼的線程進(jìn)行等待,把線程放到等待隊(duì)列中
  • 釋放當(dāng)前的鎖
  • 滿足一定條件時(shí)被喚醒,重新嘗試獲取這個(gè)鎖

notify方法

notify時(shí)喚醒等待的線程

  • 方法notify()也要在同步方法或同步塊中調(diào)用,該方法是用來(lái)通知那些可能等待該對(duì)象的對(duì)象鎖的其他線程,對(duì)其發(fā)出通知,并使它們重新獲取該對(duì)象的鎖
  • 如果多個(gè)線程等待,則由線程調(diào)度器隨機(jī)挑選出一個(gè)wait狀態(tài)的線程(沒有先來(lái)后到)

定時(shí)器

在標(biāo)準(zhǔn)庫(kù)中java.util.Timer

如下是一個(gè)簡(jiǎn)單的使用示例:

主線程執(zhí)行schedule方法的時(shí)候,就是把這個(gè)任務(wù)給放到timer對(duì)象中,與此同時(shí),timer里頭也包含一個(gè)線程,這個(gè)線程叫做“掃描線程”,一旦時(shí)間到,掃描線程就會(huì)執(zhí)行剛才安排的任務(wù)了,Timer里可以安排多個(gè)任務(wù)的。

Timer timer=new Timer();
timer.schedule(new TimerTask() {
??? @Override
??? public void run() {
??????? System.out.println("時(shí)間到了");
??? }
},2000);
System.out.println("程序開始");

此處傳參使用匿名內(nèi)部類的寫法,繼承了TimerTask,并且創(chuàng)建出一個(gè)實(shí)例,TimerTask實(shí)現(xiàn)了Runnable接口,以此來(lái)重寫run方法,通過run描述任務(wù)的詳細(xì)情況。

public abstract class TimerTask implements Runnable?

線程池?

線程池就是把線程創(chuàng)建好,放到池子里,后續(xù)用的時(shí)候直接從池子里取,這樣效率會(huì)比我們每次都新創(chuàng)建線程,效率更高。

那么為什么從線程池里取的效率會(huì)比新創(chuàng)建線程效率更高呢?

線程池的創(chuàng)建

線程池對(duì)象不是我們直接new的,而是通過一個(gè)專門的方法,返回一個(gè)線程池對(duì)象,如下:

ExecutorService service= Executors.newCachedThreadPool();

這種方法就是采用工廠模式 ,Executors是一個(gè)工廠類,newCachedThreadPool()是一個(gè)工廠方法。

newCachedThreadPool線程池里的線程用過之后不著急釋放,以備隨時(shí)再使用,此時(shí)構(gòu)造出來(lái)的線程池對(duì)象,有一個(gè)基本的特點(diǎn):線程數(shù)目是能夠動(dòng)態(tài)適應(yīng)的,隨著往線程池里添加任務(wù),這個(gè)線程中的線程會(huì)根據(jù)需要自動(dòng)被創(chuàng)建出來(lái)。

newFixedThreadPool這個(gè)工廠方法就是創(chuàng)建一個(gè)固定大小的線程池,如下是創(chuàng)建一個(gè)包含3個(gè)線程的線程池

ExecutorService service= Executors.newFixedThreadPool(3);

除了上述兩種工廠方法,還有?newScheduledThreadPool(),newSingleThreadExecutor(),這兩種并不常用,這里便不再介紹。

這幾個(gè)工廠方法生成的線程池,本質(zhì)上都是對(duì)一個(gè)類(ThreadPoolExecutor)進(jìn)行的封裝。

ThreadPoolExecutor構(gòu)造參數(shù):

  • int corePoolSize 核心線程數(shù)
  • int maximumPoolSize 最大線程數(shù)

這兩個(gè)參數(shù)描述了線程池中,線程的數(shù)目,這個(gè)線程池里線程的數(shù)目是可以動(dòng)態(tài)變化的,變化范圍就是[corePoolSize,maximumPoolSize]

  • long keepAliveTime? 允許非核心線程數(shù)存留時(shí)間
  • TimeUnit unit 時(shí)間單位 ms,s,min
  • BlockingQueue<Runable> workQueue 阻塞隊(duì)列,用來(lái)存放線程池中的任務(wù),可以根據(jù)需要,靈活設(shè)置這里的隊(duì)列是啥,需要優(yōu)先級(jí)就可以設(shè)置PriorityBlockingQueue,如果不需要優(yōu)先級(jí),并且任務(wù)數(shù)目是相對(duì)恒定的,可以使用ArrayBlockingQueue,如果不需要優(yōu)先級(jí),并且任務(wù)數(shù)目變動(dòng)較大的,使用LinkedBlockingQueue
  • ThreadFactory threadFactory 工廠模式的體現(xiàn),不用手動(dòng)設(shè)置屬性
  • RejectedExecutionHandler handler 線程池的拒絕策略,一個(gè)線程池能容納的任務(wù)數(shù)量,有上限,當(dāng)?shù)竭_(dá)上線的時(shí)候,做出什么樣的反應(yīng),如下是常用拒絕策略:
ThreadPoolExecutor.AbortPolicy直接拋出異常
ThreadPoolExecutor.CallerRunsPolicy新添加的任務(wù),由添加任務(wù)的線程負(fù)責(zé)執(zhí)行
ThreadPoolExecutor.DiscardOldestPolicy丟棄任務(wù)隊(duì)列中最老的任務(wù)
ThreadPoolExecutor.DiscardPolicy丟棄當(dāng)前新加的任務(wù)

常見問題:

使用線程池,需要設(shè)置線程的數(shù)目,數(shù)目設(shè)置多少合適?

????????使用實(shí)驗(yàn)的方式,對(duì)程序進(jìn)行性能測(cè)試,測(cè)試過程中嘗試修改不同的線程池的線程數(shù)目,看哪種情況更符合要求

往線程池里添加任務(wù)

通過submit往線程池里注冊(cè)任務(wù)

service.submit(new Runnable() {
??? @Override
??? public void run() {
??????? System.out.println("hello");
??? }
});

http://www.risenshineclean.com/news/8319.html

相關(guān)文章:

  • 阿里云域名注冊(cè)好了怎么做網(wǎng)站無(wú)錫網(wǎng)站建設(shè)
  • 專門做品牌網(wǎng)站設(shè)計(jì)服務(wù)seo搜索引擎優(yōu)化原理
  • 小說(shuō)網(wǎng)站的網(wǎng)編具體做哪些工作谷歌chrome瀏覽器下載
  • 做翻譯兼職的網(wǎng)站焊工培訓(xùn)內(nèi)容有哪些
  • 洛陽(yáng)網(wǎng)站建設(shè)的公司哪家好深圳網(wǎng)絡(luò)營(yíng)銷的公司哪家好
  • 海興縣網(wǎng)站建設(shè)價(jià)格診斷網(wǎng)站seo現(xiàn)狀的方法
  • 做網(wǎng)站群廈門網(wǎng)站優(yōu)化
  • 做平臺(tái)的網(wǎng)站有哪些功能廣州seo顧問seocnm
  • 南京 網(wǎng)站設(shè)計(jì)怎么做推廣和宣傳
  • 自己做網(wǎng)站怎么掙錢對(duì)網(wǎng)絡(luò)營(yíng)銷的認(rèn)識(shí)有哪些
  • 重慶公司章程怎么下載seo培訓(xùn)學(xué)校
  • 網(wǎng)站建設(shè)申報(bào)書短視頻廣告投放平臺(tái)
  • 一級(jí)做爰片c視頻網(wǎng)站怎么做網(wǎng)頁(yè)宣傳
  • 九江建設(shè)公司網(wǎng)站免費(fèi)網(wǎng)絡(luò)推廣
  • 怎么做應(yīng)援網(wǎng)站石家莊抖音seo
  • 哪個(gè)網(wǎng)站可以做面料訂單流量精靈
  • 網(wǎng)站運(yùn)營(yíng)規(guī)劃百度指數(shù)怎么看
  • 廈門網(wǎng)站建設(shè)公司哪家好河南疫情最新消息
  • 手機(jī)app是什么意思seo的范疇是什么
  • windows做網(wǎng)站服務(wù)器嗎新型網(wǎng)絡(luò)營(yíng)銷方式
  • 制作動(dòng)態(tài)網(wǎng)頁(yè)的軟件seo免費(fèi)優(yōu)化網(wǎng)址軟件
  • 制定網(wǎng)站建設(shè)方案十大接單平臺(tái)
  • 館陶縣網(wǎng)站怎么有自己的網(wǎng)站
  • 怎樣做京東網(wǎng)站最新seo新手教程
  • 日用品企業(yè)網(wǎng)站建設(shè)萬(wàn)能軟文范例800字
  • 測(cè)試網(wǎng)站兼容大數(shù)據(jù)是干什么的
  • 太原網(wǎng)站制作費(fèi)用金戈枸櫞酸西地那非片
  • 400全國(guó)服務(wù)熱線代理順德手機(jī)網(wǎng)站建設(shè)sem推廣計(jì)劃
  • 金山網(wǎng)站制作百度業(yè)務(wù)范圍
  • 浦東新區(qū)專業(yè)做網(wǎng)站seo推廣軟件排行榜