国产亚洲精品福利在线无卡一,国产精久久一区二区三区,亚洲精品无码国模,精品久久久久久无码专区不卡

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

榆林做網(wǎng)站的公司免費seo網(wǎng)站推廣在線觀看

榆林做網(wǎng)站的公司,免費seo網(wǎng)站推廣在線觀看,網(wǎng)站建設(shè) 國鴻,如何做視頻網(wǎng)站的會員代理本系列會更新我在學(xué)習(xí)juc時的筆記和自己的一些思想記錄。如有問題歡迎聯(lián)系。 并發(fā)編程 進(jìn)程與線程 1.進(jìn)程和線程的概念 程序是靜態(tài)的,進(jìn)程是動態(tài)的 進(jìn)程 程序由指令和數(shù)據(jù)組成,但這些指令要運行,數(shù)據(jù)要讀寫,就必須將指令加載…

本系列會更新我在學(xué)習(xí)juc時的筆記和自己的一些思想記錄。如有問題歡迎聯(lián)系。

并發(fā)編程

進(jìn)程與線程

1.進(jìn)程和線程的概念

程序是靜態(tài)的,進(jìn)程是動態(tài)的

進(jìn)程
  • 程序由指令和數(shù)據(jù)組成,但這些指令要運行,數(shù)據(jù)要讀寫,就必須將指令加載至 CPU,數(shù)據(jù)加載至內(nèi)存。在指令運行過程中還需要用到磁盤、網(wǎng)絡(luò)等設(shè)備。進(jìn)程就是用來加載指令、管理內(nèi)存、管理 IO 的
  • 當(dāng)一個程序被運行,從磁盤加載這個程序的代碼至內(nèi)存,這時就開啟了一個進(jìn)程。
  • 進(jìn)程就可以視為程序的一個實例。大部分程序可以同時運行多個實例進(jìn)程(例如記事本、畫圖、瀏覽器等),也有的程序只能啟動一個實例進(jìn)程(例如網(wǎng)易云音樂、360 安全衛(wèi)士等)
線程
  • 一個進(jìn)程之內(nèi)可以分為一到多個線程。
  • 一個線程就是一個指令流,將指令流中的一條條指令以一定的順序交給 CPU 執(zhí)行
  • Java 中,線程作為最小調(diào)度單位,進(jìn)程作為資源分配的最小單位。 在 windows 中進(jìn)程是不活動的,只是作為線程的容器
進(jìn)程和線程對比
  • 進(jìn)程基本上相互獨立的,而線程存在于進(jìn)程內(nèi),是進(jìn)程的一個子集
  • 進(jìn)程擁有共享的資源,如內(nèi)存空間等,供其內(nèi)部的線程共享
  • 進(jìn)程間通信較為復(fù)雜:同一臺計算機(jī)的進(jìn)程通信稱為 IPC(Inter-process communication)。不同計算機(jī)之間的進(jìn)程通信,需要通過網(wǎng)絡(luò),并遵守共同的協(xié)議,例如 HTTP
  • 線程通信相對簡單,因為它們共享進(jìn)程內(nèi)的內(nèi)存,一個例子是多個線程可以訪問同一個共享變量
  • 線程更輕量,線程上下文切換成本一般上要比進(jìn)程上下文切換低

2.并行和并發(fā)的概念

并發(fā)

并發(fā)能力:同一時間應(yīng)對多件事情的能力。

單核 cpu 下,線程實際還是 串行執(zhí)行 的。操作系統(tǒng)中有一個組件叫做任務(wù)調(diào)度器,將 cpu 的時間片(windows下時間片最小約為 15 毫秒)分給不同的程序使用,只是由于 cpu 在線程間(時間片很短)的切換非???#xff0c;人類感覺是 同時運行的 ??偨Y(jié)為一句話就是: 微觀串行,宏觀并行 ,一般會將這種 線程輪流使用 CPU 的做法稱為并發(fā), concurrent。

并行

多核 cpu下,每個 核(core) 都可以調(diào)度運行線程,這時候線程可以是并行的。

引用 Rob Pike 的一段描述:

  • 并發(fā)(concurrent)是同一時間應(yīng)對(dealing with)多件事情的能力
  • 并行(parallel)是同一時間動手做(doing)多件事情的能力

例子:

3.線程基本應(yīng)用

應(yīng)用之異步調(diào)用(案例1)

以調(diào)用方角度來講,如果

  • 需要等待結(jié)果返回,才能繼續(xù)運行就是同步
  • 不需要等待結(jié)果返回,就能繼續(xù)運行就是異步

1)?設(shè)計

多線程可以讓方法執(zhí)行變?yōu)楫惒降?#xff08;即不要巴巴干等著)比如說讀取磁盤文件時,假設(shè)讀取操作花費了 5 秒鐘,如果沒有線程調(diào)度機(jī)制,這 5 秒 cpu 什么都做不了,其它代碼都得暫停...

//同步
@Slf4j(topic =?"c.Sync")
public?class?Sync {

????public?static?void?main(String[]?args)?{
????????FileReader.read(Constants.MP4_FULL_PATH);
????????log.debug("do other things ...");
????}

}

//異步
@Slf4j(topic =?"c.Async")
public?class?Async {

????public?static?void?main(String[]?args)?{
????????new?Thread(()?->?FileReader.read(Constants.MP4_FULL_PATH)).start();
????????log.debug("do other things ...");
????}

}

2)?結(jié)論

  • 比如在項目中,視頻文件需要轉(zhuǎn)換格式等操作比較費時,這時開一個新線程處理視頻轉(zhuǎn)換,避免阻塞主線程
  • tomcat 的異步 servlet 也是類似的目的,讓用戶線程處理耗時較長的操作,避免阻塞 tomcat 的工作線程
  • ui 程序中,開線程進(jìn)行其他操作,避免阻塞 ui 線程

充分利用多核 cpu 的優(yōu)勢,提高運行效率。想象下面的場景,執(zhí)行 3 個計算,最后將計算結(jié)果匯總。

計算 1 花費 10 ms
計算 2 花費 11 ms
計算 3 花費 9 ms
匯總需要 1 ms

  • 如果是串行執(zhí)行,那么總共花費的時間是 10 + 11 + 9 + 1 = 31ms
  • 但如果是四核 cpu,各個核心分別使用線程 1 執(zhí)行計算 1,線程 2 執(zhí)行計算 2,線程 3 執(zhí)行計算 3,那么 3 個線程是并行的,花費時間只取決于最長的那個線程運行的時間,即 11ms 最后加上匯總時間只會花費 12ms

注意
需要在多核 cpu 才能提高效率,單核仍然時是輪流執(zhí)行

1)?設(shè)計

@Fork(1)
@BenchmarkMode(Mode.AverageTime)//測試模式,統(tǒng)計程序平均時間
@Warmup(iterations=3)//熱身三次
@Measurement(iterations=5)//五輪測試取平均值
public?class?MyBenchmark {
????static?int[]?ARRAY =?new?int[1000_000_00];
????static?{
????????Arrays.fill(ARRAY,?1);
????}
????@Benchmark
????public?int?c()?throws?Exception?{
????????int[]?array =?ARRAY;
????????FutureTask<Integer>?t1 =?new?FutureTask<>(()->{
????????????int?sum =?0;
????????????for(int?i =?0;?i <?250_000_00;i++)?{
????????????????sum +=?array[0+i];
????????????}
????????????return?sum;
????????});
????????FutureTask<Integer>?t2 =?new?FutureTask<>(()->{
????????????int?sum =?0;
????????????for(int?i =?0;?i <?250_000_00;i++)?{
????????????????sum +=?array[250_000_00+i];
????????????}
????????????return?sum;
????????});
????????FutureTask<Integer>?t3 =?new?FutureTask<>(()->{
????????????int?sum =?0;
????????????for(int?i =?0;?i <?250_000_00;i++)?{
????????????????sum +=?array[500_000_00+i];
????????????}
????????????return?sum;
????????});
????????FutureTask<Integer>?t4 =?new?FutureTask<>(()->{
????????????int?sum =?0;
????????????for(int?i =?0;?i <?250_000_00;i++)?{
????????????????sum +=?array[750_000_00+i];
????????????}
????????????return?sum;
????????});
????????new?Thread(t1).start();
????????new?Thread(t2).start();
????????new?Thread(t3).start();
????????new?Thread(t4).start();
????????return?t1.get()?+?t2.get()?+?t3.get()+?t4.get();
????}
????@Benchmark
????public?int?d()?throws?Exception?{
????????int[]?array =?ARRAY;
????????FutureTask<Integer>?t1 =?new?FutureTask<>(()->{
????????????int?sum =?0;
????????????for(int?i =?0;?i <?1000_000_00;i++)?{
????????????????sum +=?array[0+i];
????????????}
????????????return?sum;
????????});
????????new?Thread(t1).start();
????????return?t1.get();
????}
}

在單核的情況下,多線程和單線程效率基本一致,多線程會有上下文切換的耗時。

在多核的情況下,多線程比單線程就會效率翻倍。

2)?結(jié)論

單核 cpu 下,多線程不能實際提高程序運行效率,只是為了能夠在不同的任務(wù)之間切換,不同線程輪流使用cpu ,不至于一個線程總占用 cpu,別的線程沒法干活。

多核 cpu 可以并行跑多個線程,但能否提高程序運行效率還是要分情況的。

  • 有些任務(wù),經(jīng)過精心設(shè)計,將任務(wù)拆分,并行執(zhí)行,當(dāng)然可以提高程序的運行效率。但不是所有計算任務(wù)都能拆分(參考后文的【阿姆達(dá)爾定律】)
  • 也不是所有任務(wù)都需要拆分,任務(wù)的目的如果不同,談拆分和效率沒啥意義

IO 操作不占用 cpu,只是我們一般拷貝文件使用的是【阻塞 IO】,這時相當(dāng)于線程雖然不用 cpu,但需要一直等待 IO 結(jié)束,沒能充分利用線程。所以才有后面的【非阻塞 IO】和【異步 IO】優(yōu)化

Java線程

1.創(chuàng)建和運行線程

創(chuàng)建線程對象

// 創(chuàng)建線程對象
Thread?t =?new?Thread()?{
?public?void?run()?{
?// 要執(zhí)行的任務(wù)
?}
};
// 啟動線程,交給任務(wù)調(diào)度器,分配時間片,交給時間片去執(zhí)行。
t.start();

例如:

方法一:直接使用?Thread

@Slf4j(topic =?"c.Test1")
public?class?Test1 {

????public?static?void?test2()?{

????????Thread?t =?new?Thread(()->{?log.debug("running");?},?"t2");

????????t.start();
????}
????public?static?void?test1()?{
????????//匿名內(nèi)部類的寫法
????????Thread?t =?new?Thread(){
????????????@Override
????????????public?void?run()?{
????????????????log.debug("running");
????????????}
????????};
????????//創(chuàng)建線程的時候可以給其指定名稱
????????t.setName("t1");
????????t.start();

????}
}

方法二:使用?Runnable?配合?Thread

把【線程】和【任務(wù)】(要執(zhí)行的代碼)分開

  • Thread 代表線程
  • Runnable 可運行的任務(wù)(線程要執(zhí)行的代碼)

Runnable源碼,如果接口中有@FunctionalInterface注解,則可以被lambda簡化。如果一個接口中有多個抽象接口,是沒辦法用lambda簡化的。

@FunctionalInterface
public?interface?Runnable?{
????/**
?????*?When an object implementing interface <code>Runnable</code>?is used
?????*?to create a thread,?starting the thread causes the object's
?????*?<code>run</code>?method to be called in that separately executing
?????*?thread.
?????*?<p>
?????*?The general contract of the method <code>run</code>?is that it may
?????*?take any action whatsoever.
?????*
?????*?@see ????java.lang.Thread#run()
?????*/
????public?abstract?void?run();
}

@Slf4j(topic =?"c.Test2")
public?class?Test2 {
????public?static?void?main(String[]?args)?{
????????//果接口中有@FunctionalInterface注解,則可以被lambda簡化
????????Runnable?r =?()?->?{log.debug("running");};

????????Thread?t =?new?Thread(r,?"t2");

????????t.start();
????}
}

原理之?Thread??Runnable?的關(guān)系

分析 Thread 的源碼,理清它與 Runnable 的關(guān)系

小結(jié)

  • 方法1 是把線程和任務(wù)合并在了一起,方法2 是把線程和任務(wù)分開了
  • 用 Runnable 更容易與線程池等高級 API 配合
  • 用 Runnable 讓任務(wù)類脫離了 Thread 繼承體系,更靈活

都是走的線程里的run方法。

方法三:FutureTask 配合?Thread

FutureTask 能夠接收 Callable 類型的參數(shù),用來處理有返回結(jié)果的情況

FutureTask源碼分析:

實現(xiàn)一個RunnableFuture的接口

public?class?FutureTask<V>?implements?RunnableFuture<V>?{

RunnableFuture接口又繼承了Runnable和Future

public?interface?RunnableFuture<V>?extends?Runnable,?Future<V>?{
????/**
?????*?Sets this Future to the result of its computation
?????*?unless it has been cancelled.
?????*/
????void?run();
}

Future里有g(shù)et方法返回任務(wù)執(zhí)行結(jié)果

????V get()?throws?InterruptedException,?ExecutionException;

????/**
?????*?Waits if necessary for at most the given time for the computation
?????*?to complete,?and then retrieves its result,?if available.
?????*
?????*?@param timeout the maximum time to wait
?????*?@param unit the time unit of the timeout argument
?????*?@return the computed result
?????*?@throws CancellationException if the computation was cancelled
?????*?@throws ExecutionException if the computation threw an
?????*?exception
?????*?@throws InterruptedException if the current thread was interrupted
?????*?while waiting
?????*?@throws TimeoutException if the wait timed out
?????*/
????V get(long?timeout,?TimeUnit?unit)
????????throws?InterruptedException,?ExecutionException,?TimeoutException;

Callable源碼分析

Callable可以配合FutureTask讓任務(wù)執(zhí)行完了,將結(jié)果傳給其他線程

能拋出異常

@FunctionalInterface
public?interface?Callable<V>?{
????/**
?????*?Computes a result,?or throws an exception if unable to do so.
?????*
?????*?@return computed result
?????*?@throws Exception if unable to compute a result
?????*/
????V call()?throws?Exception;
}

實例代碼:


// 創(chuàng)建任務(wù)對象
FutureTask<Integer>?task3 =?new?FutureTask<>(()?->?{
?log.debug("hello");
?return?100;
});
// 參數(shù)1 是任務(wù)對象; 參數(shù)2 是線程名字,推薦
new?Thread(task3,?"t3").start();
// 主線程阻塞,同步等待 task 執(zhí)行完畢的結(jié)果
Integer?result =?task3.get();
log.debug("結(jié)果是:{}",?result);

輸出:

19:22:27 [t3] c.ThreadStarter - hello
19:22:27 [main] c.ThreadStarter - 結(jié)果是:100

2.查看進(jìn)程線程的方法

windows
  • 任務(wù)管理器可以查看進(jìn)程和線程數(shù),也可以用來殺死進(jìn)程
  • tasklist 查看進(jìn)程 (tasklist | findstr java)
  • taskkill 殺死進(jìn)程 (taskkill /F /PID 280660)
linux
  • ps -fe 查看所有進(jìn)程
  • ps -fT -p ?查看某個進(jìn)程(PID)的所有線程
  • kill 殺死進(jìn)程
  • top 按大寫 H 切換是否顯示線程
  • top -H -p ?查看某個進(jìn)程(PID)的所有線程
Java
  • jps 命令查看所有 Java 進(jìn)程
  • jstack ?查看某個 Java 進(jìn)程(PID)的所有線程狀態(tài)
  • jconsole 來查看某個 Java 進(jìn)程中線程的運行情況(圖形界面)可以在window+r里直接打印

jconsole 遠(yuǎn)程監(jiān)控配置

  • 需要以如下方式運行你的 java 類

java -Djava.rmi.server.hostname=`ip地址` -Dcom.sun.management.jmxremote -
Dcom.sun.management.jmxremote.port=`連接端口` -Dcom.sun.management.jmxremote.ssl=是否安全連接 -
Dcom.sun.management.jmxremote.authenticate=是否認(rèn)證 java類

不需要就false,ip地址和連接端口在輸入后記得把`去掉

  • 修改 /etc/hosts 文件將 127.0.0.1 映射至主機(jī)名

如果要認(rèn)證訪問,還需要做如下步驟

  • 復(fù)制 jmxremote.password 文件
  • 修改 jmxremote.password 和 jmxremote.access 文件的權(quán)限為 600 即文件所有者可讀寫
  • 連接時填入 controlRole(用戶名),R&D(密碼)

3.線程運行的原理

棧與棧幀

ava Virtual Machine Stacks (Java 虛擬機(jī)棧)

我們都知道 JVM 中由堆、棧、方法區(qū)所組成,其中棧內(nèi)存是給誰用的呢?其實就是線程,每個線程啟動后,虛擬機(jī)就會為其分配一塊棧內(nèi)存。

  • 每個棧由多個棧幀(Frame)組成,對應(yīng)著每次方法調(diào)用時所占用的內(nèi)存
  • 每個線程只能有一個活動棧幀,對應(yīng)著當(dāng)前正在執(zhí)行的那個方法
線程上下文切換(Thread Context Switch

因為以下一些原因?qū)е?cpu 不再執(zhí)行當(dāng)前的線程,轉(zhuǎn)而執(zhí)行另一個線程的代碼

  • 線程的 cpu 時間片用完
  • 垃圾回收
  • 有更高優(yōu)先級的線程需要運行
  • 線程自己調(diào)用了 sleep、yield、wait、join、park、synchronized、lock 等方法

當(dāng) Context Switch 發(fā)生時,需要由操作系統(tǒng)保存當(dāng)前線程的狀態(tài),并恢復(fù)另一個線程的狀態(tài),Java 中對應(yīng)的概念就是程序計數(shù)器(Program Counter Register),它的作用是記住下一條 jvm 指令的執(zhí)行地址,是線程私有的

  • 狀態(tài)包括程序計數(shù)器、虛擬機(jī)棧中每個棧幀的信息,如局部變量、操作數(shù)棧、返回地址等
  • Context Switch 頻繁發(fā)生會影響性能

4.線程

4.1start與run

調(diào)用run

public?static?void?main(String[]?args)?{
?Thread?t1 =?new?Thread("t1")?{
?@Override
?public?void?run()?{
?log.debug(Thread.currentThread().getName());
?FileReader.read(Constants.MP4_FULL_PATH);
?}
?};
?t1.run();
?log.debug("do other things ...");
}

輸出:

是主線程main來調(diào)用run方法,程序仍在 main 線程運行, FileReader.read() 方法調(diào)用還是同步的

19:39:14?[main]?c.TestStart?-?main
19:39:14?[main]?c.FileReader?-?read [1.mp4]?start ...
19:39:18?[main]?c.FileReader?-?read [1.mp4]?end ...?cost:?4227?ms
19:39:18?[main]?c.TestStart?-?do?other things ...

調(diào)用?start

t1.start();

輸出:

19:41:30 [main] c.TestStart - do other things ...
19:41:30 [t1] c.TestStart - t1
19:41:30 [t1] c.FileReader - read [1.mp4] start ...
19:41:35 [t1] c.FileReader - read [1.mp4] end ... cost: 4542 ms

程序在 t1 線程運行, FileReader.read() 方法調(diào)用是異步的

小結(jié):

  • 直接調(diào)用 run 是在主線程中執(zhí)行了 run,沒有啟動新的線程
  • 使用 start 是啟動新的線程,通過新的線程間接執(zhí)行 run 中的代碼

4.2sleep與yield

sleep

  • 調(diào)用 sleep 會讓當(dāng)前線程從 Running?進(jìn)入 Timed Waiting?狀態(tài)(阻塞)
  • 其它線程可以使用 interrupt 方法打斷正在睡眠的線程,這時 sleep 方法會拋出 InterruptedException
  • 睡眠結(jié)束后的線程未必會立刻得到執(zhí)行(未必能立刻獲得cpu使用權(quán))
  • 建議用 TimeUnit 的 sleep 代替 Thread 的 sleep 來獲得更好的可讀性
http://m.aloenet.com.cn/news/34128.html

相關(guān)文章:

  • 網(wǎng)站模板做網(wǎng)站網(wǎng)絡(luò)營銷管理名詞解釋
  • 網(wǎng)站開發(fā)和軟件北京搜索優(yōu)化排名公司
  • wordpress滑動驗證2016汕頭網(wǎng)站建設(shè)方案優(yōu)化
  • 重慶做網(wǎng)站重慶做網(wǎng)站企業(yè)網(wǎng)站推廣方法實驗報告
  • 新興縣城鄉(xiāng)建設(shè)局網(wǎng)站云搜索app下載
  • 廣告型網(wǎng)站建設(shè)成人本科
  • 濰坊做網(wǎng)站的那家好網(wǎng)絡(luò)推廣公司名字大全
  • 北京公司網(wǎng)站制作電話網(wǎng)絡(luò)營銷推廣外包服務(wù)
  • 香港服務(wù)器做網(wǎng)站日照網(wǎng)絡(luò)推廣公司
  • 基于php技術(shù)的網(wǎng)站建設(shè)關(guān)鍵詞優(yōu)化推廣公司
  • 網(wǎng)站建設(shè)簡稱什么網(wǎng)絡(luò)營銷工具的特點
  • dede 手機(jī)網(wǎng)站模板seo整站優(yōu)化方案
  • 電信100m光纖做網(wǎng)站windows優(yōu)化軟件
  • 隨州網(wǎng)站建設(shè)網(wǎng)站設(shè)計與制作教程
  • 中國制造網(wǎng) 做網(wǎng)站費用網(wǎng)站測試的內(nèi)容有哪些
  • 自己做的網(wǎng)站百度收索不到友鏈互換平臺推薦
  • 怎么做送餐網(wǎng)站做網(wǎng)絡(luò)推廣的網(wǎng)站有哪些
  • 門頭溝住房和城鄉(xiāng)建設(shè)委員會官網(wǎng)站他達(dá)那非片能延時多久
  • 做的網(wǎng)站侵犯美的商標(biāo)賠償多少錢廣州網(wǎng)絡(luò)推廣公司
  • 網(wǎng)站天天做收錄有效果嗎google中文搜索引擎入口
  • 杭州醫(yī)療器械網(wǎng)站制作app開發(fā)價格表
  • 合肥網(wǎng)站建設(shè)工作室企業(yè)qq多少錢一年
  • 貴州建設(shè)廳監(jiān)理協(xié)會網(wǎng)站汕頭網(wǎng)站設(shè)計公司
  • 怎么做中英文版網(wǎng)站國內(nèi)搜索引擎排名
  • 網(wǎng)站內(nèi)容及實現(xiàn)方式qq代刷網(wǎng)站推廣
  • 怎么描述網(wǎng)站主頁做的好關(guān)鍵詞排名的工具
  • 廣州網(wǎng)站 制作信科便宜制作網(wǎng)頁的基本步驟
  • 濰坊網(wǎng)站建設(shè)價格百度云搜索入口
  • wordpress get_the_post_thumbnail石家莊百度搜索優(yōu)化
  • 網(wǎng)站開發(fā)上線流程圖歐美網(wǎng)站建設(shè)公司