java多線程學習與總結(java多線程處理數據)

本文目錄一覽:

北大青鳥java培訓:Java多線程問題總結?

Java多線程分類中寫了21篇多線程的文章,21篇文章的內容很多,個人認為,學習,內容越多、越雜的知識,越需要進行深刻的總結,這樣才能記憶深刻,將知識變成自己的。

java課程培訓機構認為這篇文章主要是對多線程的問題進行總結的,因此羅列了多個多線程的問題。

這些多線程的問題,有些來源於各大網站、有些來源於自己的思考。

(1)發揮多核CPU的優勢隨著工業的進步,現在的筆記本、台式機乃至商用的應用伺服器至少也都是雙核的,4核、8核甚至16核的也都不少見,如果是單線程的程序,那麼在雙核CPU上就浪費了50%,在4核CPU上就浪費了75%。

單核CPU上所謂的」多線程」那是假的多線程,同一時間處理器只會處理一段邏輯,只不過線程之間切換得比較快,看著像多個線程」同時」運行罷了。

多核CPU上的多線程才是真正的多線程,它能讓你的多段邏輯同時工作,多線程,可以真正發揮出多核CPU的優勢來,達到充分利用CPU的目的。

(2)防止阻塞從程序運行效率的角度來看,單核CPU不但不會發揮出多線程的優勢,反而會因為在單核CPU上運行多線程導致線程上下文的切換,而降低程序整體的效率。

但是單核CPU我們還是要應用多線程,就是為了防止阻塞。

試想,如果單核CPU使用單線程,那麼只要這個線程阻塞了,比方說遠程讀取某個數據吧,對端遲遲未返回又沒有設置超時時間,那麼你的整個程序在數據返回回來之前就停止運行了。

多線程可以防止這個問題,多條線程同時運行,哪怕一條線程的代碼執行讀取數據阻塞,也不會影響其它任務的執行。

(3)便於建模這是另外一個沒有這麼明顯的優點了。

假設有一個大的任務A,單線程編程,那麼就要考慮很多,建立整個程序模型比較麻煩。

但是如果把這個大的任務A分解成幾個小任務,任務B、任務C、任務D,分別建立程序模型,並通過多線程分別運行這幾個任務,那就簡單很多了。

多線程回顧筆記總結

三種創建方式:

// 練習Thread,實現多線程同步下載圖片

public class TestThread1 extends Thread {

private String name; // 保存文件名

// 創建一個構造器

public TestThread1(String url, String name) {

this.url = url;

this.name = name;

}

public static void main(String[] args) {

TestThread1 testThread1 = new TestThread1(“;z=0ipn=falseword=qq%E5%A4%B4%E5%83%8Fhs=0pn=4spn=0di=179850pi=0rn=1tn=baiduimagedetailis=0%2C0ie=utf-8oe=utf-8cl=2lm=-1cs=1462782358%2C2840615474os=332435882%2C2135675601simid=3516664974%2C458125993adpicid=0lpn=0ln=30fr=alafm=sme=cg=headbdtype=0oriquery=qq%E5%A4%B4%E5%83%8Fobjurl=http%3A%2F%2F;fromurl=ippr_z2C%24qAzdH3FAzdH3Fooo_z%26e3B8-jyj_z%26e3BvgAzdH3FQQ%25E0%25l9%25AF%25EF%25Bl%25ba%25E0%25ln%25A0%25Em%25BE%25Bm%25Em%25lD%25l8%25Ec%25b9%25lA_z%26e3Bip4sgsm=5islist=querylist=”,”1.jpg”);

TestThread1 testThread2 = new TestThread1(“;z=0ipn=falseword=qq%E5%A4%B4%E5%83%8Fhs=0pn=8spn=0di=18480pi=0rn=1tn=baiduimagedetailis=0%2C0ie=utf-8oe=utf-8cl=2lm=-1cs=1756505232%2C2129310927os=3725694615%2C3696011658simid=3576571828%2C474240706adpicid=0lpn=0ln=30fr=alafm=sme=cg=headbdtype=0oriquery=qq%E5%A4%B4%E5%83%8Fobjurl=http%3A%2F%2F;fromurl=ippr_z2C%24qAzdH3FAzdH3F80qq_z%26e3Bv54AzdH3Fqqp57xtwg2AzdH3F8899l9m_rn_z%26e3Bip4sgsm=5islist=querylist=”,”2.jpg”);

TestThread1 testThread3 = new TestThread1(“;z=0ipn=falseword=qq%E5%A4%B4%E5%83%8Fhs=0pn=25spn=0di=132220pi=0rn=1tn=baiduimagedetailis=0%2C0ie=utf-8oe=utf-8cl=2lm=-1cs=1226648351%2C4217836os=1652635041%2C3404961290simid=3325093720%2C338083432adpicid=0lpn=0ln=30fr=alafm=sme=cg=headbdtype=0oriquery=qq%E5%A4%B4%E5%83%8Fobjurl=http%3A%2F%2F;fromurl=ippr_z2C%24qAzdH3FAzdH3Fooo_z%26e3Bprbb_z%26e3BgjpAzdH3Fp57xtwg2p7rtwgAzdH3Fgwgfijg2p57xtwg2AzdH3Fda8lAzdH3F8d89AzdH3F8dnb0_z%26e3Bip4sgsm=5islist=querylist=”,”3.jpg”);

testThread1.start();

testThread2.start();

testThread3.start();

/* 結果,說明線程不是按代碼先後順序執行的,是同時執行的

下載了文件,名為:3.jpg

下載了文件,名為:1.jpg

下載了文件,名為:2.jpg

*/

}

// 下載圖片的線程執行體

@Override

public void run() {

WebDownLoader webDownLoader = new WebDownLoader();

webDownLoader.downLoader(url,name);

System.out.println(“下載了文件,名為:”+name);

}

}

// 下載器

class WebDownLoader {

// 下載方法

public void downLoader(String url,String name) {

try {

// copyURLToFile(),這個方法就是把網上的一個url變成一個文件

FileUtils.copyURLToFile(new URL(url),new File(name));

} catch (IOException e) {

e.printStackTrace();

System.out.println(“IO異常,downLoader方法出錯”);

}

}

}

// 創建線程方式2:實現Runnable介面,重寫run()方法,執行線程需要丟入Runnable介面實現類,調用start()方法

public class TestThread2 implements Runnable {

public static void main(String[] args) {

// 創建Runnable 介面實現類對象

TestThread2 testThread2 = new TestThread2();

// 創建線程對象,通過線程對象來開啟我們的線程,代理

Thread thread = new Thread(testThread2);

thread.start();

//new Thread(testThread2).start(); // 簡寫方法

for (int i = 0; i 2000; i++) {

System.out.println(“我們在學習多線程—“+i);

}

}

@Override

public void run() {

for (int i = 0; i 2000; i++) {

System.out.println(“我們在玩 遊戲 啦—“+i);

}

}

}

發現問題:多個線程操作同一個資源情況下,線程不安全,數據紊亂,出現重複數據

// 模擬龜兔賽跑

public class Race implements Runnable {

// 勝利者

private static String winner;

@Override

public void run() {

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

winner = Thread.currentThread().getName();

System.out.println(“winner is ” + winner);

return true;

}

}

return false;

}

public static void main(String[] args) {

Race race = new Race();

new Thread(race, “兔子”).start();

new Thread(race, “烏龜”).start();

}

}

關閉服務:executorService.shutdownNow();

// 線程創建方式三:實現Callable介面

/*

* Callable的好處

* 1.可以定義返回值

* 2.可以拋出異常

**/

public class TestCallable implements Callable {

private String name; // 保存文件名

// 創建一個構造器

public TestCallable(String url, String name) {

this.url = url;

this.name = name;

}

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

TestCallable testThread1 = new TestCallable(“;z=0ipn=falseword=qq%E5%A4%B4%E5%83%8Fhs=0pn=4spn=0di=179850pi=0rn=1tn=baiduimagedetailis=0%2C0ie=utf-8oe=utf-8cl=2lm=-1cs=1462782358%2C2840615474os=332435882%2C2135675601simid=3516664974%2C458125993adpicid=0lpn=0ln=30fr=alafm=sme=cg=headbdtype=0oriquery=qq%E5%A4%B4%E5%83%8Fobjurl=http%3A%2F%2F;fromurl=ippr_z2C%24qAzdH3FAzdH3Fooo_z%26e3B8-jyj_z%26e3BvgAzdH3FQQ%25E0%25l9%25AF%25EF%25Bl%25ba%25E0%25ln%25A0%25Em%25BE%25Bm%25Em%25lD%25l8%25Ec%25b9%25lA_z%26e3Bip4sgsm=5islist=querylist=”,”1.jpg”);

TestCallable testThread2 = new TestCallable(“;z=0ipn=falseword=qq%E5%A4%B4%E5%83%8Fhs=0pn=8spn=0di=18480pi=0rn=1tn=baiduimagedetailis=0%2C0ie=utf-8oe=utf-8cl=2lm=-1cs=1756505232%2C2129310927os=3725694615%2C3696011658simid=3576571828%2C474240706adpicid=0lpn=0ln=30fr=alafm=sme=cg=headbdtype=0oriquery=qq%E5%A4%B4%E5%83%8Fobjurl=http%3A%2F%2F;fromurl=ippr_z2C%24qAzdH3FAzdH3F80qq_z%26e3Bv54AzdH3Fqqp57xtwg2AzdH3F8899l9m_rn_z%26e3Bip4sgsm=5islist=querylist=”,”2.jpg”);

TestCallable testThread3 = new TestCallable(“;z=0ipn=falseword=qq%E5%A4%B4%E5%83%8Fhs=0pn=25spn=0di=132220pi=0rn=1tn=baiduimagedetailis=0%2C0ie=utf-8oe=utf-8cl=2lm=-1cs=1226648351%2C4217836os=1652635041%2C3404961290simid=3325093720%2C338083432adpicid=0lpn=0ln=30fr=alafm=sme=cg=headbdtype=0oriquery=qq%E5%A4%B4%E5%83%8Fobjurl=http%3A%2F%2F;fromurl=ippr_z2C%24qAzdH3FAzdH3Fooo_z%26e3Bprbb_z%26e3BgjpAzdH3Fp57xtwg2p7rtwgAzdH3Fgwgfijg2p57xtwg2AzdH3Fda8lAzdH3F8d89AzdH3F8dnb0_z%26e3Bip4sgsm=5islist=querylist=”,”3.jpg”);

// 創建執行服務

ExecutorService executorService = Executors.newFixedThreadPool(3);

// 提交執行

Future submit1 = executorService.submit(testThread1);

Future submit2 = executorService.submit(testThread2);

Future submit3 = executorService.submit(testThread3);

// 獲取結果

Boolean b1 = submit1.get();

Boolean b2 = submit2.get();

Boolean b3 = submit3.get();

// 關閉服務

executorService.shutdownNow();

System.out.println(b1);

System.out.println(b2);

System.out.println(b3);

/* 結果,說明線程不是按代碼先後順序執行的,是同時執行的

下載了文件,名為:3.jpg

下載了文件,名為:1.jpg

下載了文件,名為:2.jpg

*/

}

// 下載圖片的線程執行體

@Override

public Boolean call() {

WebDownLoader webDownLoader = new WebDownLoader();

webDownLoader.downLoader(url,name);

System.out.println(“下載了文件,名為:”+name);

return true;

}

}

// 下載器

class WebDownLoader {

// 下載方法

public void downLoader(String url,String name) {

try {

// copyURLToFile(),這個方法就是把網上的一個url變成一個文件

FileUtils.copyURLToFile(new URL(url),new File(name));

} catch (IOException e) {

e.printStackTrace();

System.out.println(“IO異常,downLoader方法出錯”);

}

}

}

靜態代理模式總結:

真實對象和代理對象都要實現同一個介面

代理對象要代理真實角色

代理模式的好處:

代理對象可以做很多真實對象做不了的事情

真實對象專註做自己的事情就可以了, 其他的事情交給代理公司來做

new Thread(()- System.out.println(“我愛你啊”)).start();

public abstract void run();

}

五大狀態:

// 測試Stop

// 1.建議線程正常停止,利用次數,不建議死循環

// 2.建議使用標誌位,設置一個標誌位

// 3.不要使用stop(),destroy()方法,已過時

public class StopTest implements Runnable {

// 1 設置一個標誌位

private boolean flag = true;

public static void main(String[] args) {

StopTest stopTest = new StopTest();

// 開啟線程

new Thread(stopTest).start();

for (int i = 0; i 1000; i++) {

System.out.println(“main Thread is running…”+i);

if (i == 900) {

// 調用stop方法切換標誌位停止線程

stopTest.stop();

System.out.println(“Thread is stopped…”);

}

}

}

// 設置一個公開的方法停止線程,轉換標誌位

public void stop() {

this.flag = false;

}

@Override

public void run() {

int i = 0;

while (flag) {

System.out.println(“Thread is running…”+ i++);

}

}

}

yield

jion

daemon

// 化妝的方法,互相持有對方的鎖,就是需要拿到對方的資源

private void makeup() throws InterruptedException {

if (choice == 0) {

synchronized (lipstick) { // 獲得口紅的鎖

System.out.println(this.girlName+”獲得口紅的鎖”);

Thread.sleep(1000);

synchronized (mirror) { // 一秒後想獲得鏡子的鎖

System.out.println(this.girlName+”獲得鏡子的鎖”);

}

}

} else {

synchronized (mirror) { // 獲得鏡子的鎖

System.out.println(this.girlName+”獲得鏡子的鎖”);

Thread.sleep(2000);

synchronized (lipstick) { // 一秒後想獲得口紅的鎖

System.out.println(this.girlName+”獲得口紅的鎖”);

}

}

}

}

這樣synchronized 塊包裹著,就會導致程序卡死,只要不包裹著,就可以正常運行,如下:

// 死鎖,多個線程互相抱著對方需要的資源,然後形成僵持

public class DeadLock {

public static void main(String[] args) {

Makeup bestGirl = new Makeup(0, “婕兒”);

Makeup betterGirl = new Makeup(1, “珂兒”);

bestGirl.start();

betterGirl.start();

}

}

// 口紅

class Lipstick {

}

// 鏡子

class Mirror {

}

// 化妝

class Makeup extends Thread {

// 需要的資源只有一份,用static來保證只有一份

static Mirror mirror = new Mirror();

static Lipstick lipstick = new Lipstick();

int choice; // 選擇

String girlName; // 使用化妝品的人

public Makeup(int choice, String girlName) {

this.choice = choice;

this.girlName = girlName;

}

@Override

public void run() {

// 化妝

try {

makeup();

} catch (InterruptedException e) {

e.printStackTrace();

}

}

// 化妝的方法,互相持有對方的鎖,就是需要拿到對方的資源

private void makeup() throws InterruptedException {

if (choice == 0) {

synchronized (lipstick) { // 獲得口紅的鎖

System.out.println(this.girlName+”獲得口紅的鎖”);

Thread.sleep(1000);

}

synchronized (mirror) { // 一秒後想獲得鏡子的鎖

System.out.println(this.girlName+”獲得鏡子的鎖”);

}

} else {

synchronized (mirror) { // 獲得鏡子的鎖

System.out.println(this.girlName+”獲得鏡子的鎖”);

Thread.sleep(2000);

}

synchronized (lipstick) { // 一秒後想獲得口紅的鎖

System.out.println(this.girlName+”獲得口紅的鎖”);

}

}

}

}

上面列出了死鎖的四個條件,我們只要想辦法破其中任意一個,或多個條件就可以避免死鎖發生

1.這是一個線程同步問題,生產者和消費者共享同一個資源,並且生產者和消費者之間相互依賴,互為條件.

2.Java提供了幾個方法解決線程之間的通信問題

3.解決方式1

並發協作模型「生產者/消費者模式」 —管程法

生產者將生產好的數據放入緩衝區,消費者從緩衝區拿出數據

4.解決方式2

// 測試線程池

public class PoolTest {

public static void main(String[] args) {

// 創建服務,創建池子

// newFixedThreadPool,參數為:線程池池子大小

ExecutorService service = Executors.newFixedThreadPool(10);

service.execute(new MyThread());

service.execute(new MyThread());

service.execute(new MyThread());

service.execute(new MyThread());

// 2.關閉連接

service.shutdown();

}

}

class MyThread implements Runnable {

@Override

public void run() {

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

}

}

曲靖java培訓學校告訴你Java多線程問題總結?

Java多線程分類中寫了21篇多線程的文章,21篇文章的內容很多,個人認為,學習,內容越多、越雜的知識,越需要進行深刻的總結,這樣才能記憶深刻,將知識變成自己的。java課程培訓機構認為這篇文章主要是對多線程的問題進行總結的,因此羅列了多個多線程的問題。

這些多線程的問題,有些來源於各大網站、有些來源於自己的思考。

(1)發揮多核CPU的優勢

隨著工業的進步,現在的筆記本、台式機乃至商用的應用伺服器至少也都是雙核的,4核、8核甚至16核的也都不少見,如果是單線程的程序,那麼在雙核CPU上就浪費了50%,在4核CPU上就浪費了75%。單核CPU上所謂的」多線程」那是假的多線程,同一時間處理器只會處理一段邏輯,只不過線程之間切換得比較快,看著像多個線程」同時」運行罷了。多核CPU上的多線程才是真正的多線程,它能讓你的多段邏輯同時工作,多線程,可以真正發揮出多核CPU的優勢來,達到充分利用CPU的目的。

(2)防止阻塞

從程序運行效率的角度來看,單核CPU不但不會發揮出多線程的優勢,反而會因為在單核CPU上運行多線程導致線程上下文的切換,而降低程序整體的效率。但是單核CPU我們還是要應用多線程,就是為了防止阻塞。試想,如果單核CPU使用單線程,那麼只要這個線程阻塞了,比方說遠程讀取某個數據吧,對端遲遲未返回又沒有設置超時時間,那麼你的整個程序在數據返回回來之前就停止運行了。多線程可以防止這個問題,多條線程同時運行,哪怕一條線程的代碼執行讀取數據阻塞,也不會影響其它任務的執行。

(3)便於建模

這是另外一個沒有這麼明顯的優點了。假設有一個大的任務A,單線程編程,那麼就要考慮很多,建立整個程序模型比較麻煩。但是如果把這個大的任務A分解成幾個小任務,任務B、任務C、任務D,分別建立程序模型,並通過多線程分別運行這幾個任務,那就簡單很多了。

原創文章,作者:小藍,如若轉載,請註明出處:https://www.506064.com/zh-tw/n/198361.html

(0)
打賞 微信掃一掃 微信掃一掃 支付寶掃一掃 支付寶掃一掃
小藍的頭像小藍
上一篇 2024-12-04 10:24
下一篇 2024-12-04 10:24

相關推薦

  • java client.getacsresponse 編譯報錯解決方法

    java client.getacsresponse 編譯報錯是Java編程過程中常見的錯誤,常見的原因是代碼的語法錯誤、類庫依賴問題和編譯環境的配置問題。下面將從多個方面進行分析…

    編程 2025-04-29
  • Java JsonPath 效率優化指南

    本篇文章將深入探討Java JsonPath的效率問題,並提供一些優化方案。 一、JsonPath 簡介 JsonPath是一個可用於從JSON數據中獲取信息的庫。它提供了一種DS…

    編程 2025-04-29
  • Java Bean載入過程

    Java Bean載入過程涉及到類載入器、反射機制和Java虛擬機的執行過程。在本文中,將從這三個方面詳細闡述Java Bean載入的過程。 一、類載入器 類載入器是Java虛擬機…

    編程 2025-04-29
  • Python讀取CSV數據畫散點圖

    本文將從以下方面詳細闡述Python讀取CSV文件並畫出散點圖的方法: 一、CSV文件介紹 CSV(Comma-Separated Values)即逗號分隔值,是一種存儲表格數據的…

    編程 2025-04-29
  • Java騰訊雲音視頻對接

    本文旨在從多個方面詳細闡述Java騰訊雲音視頻對接,提供完整的代碼示例。 一、騰訊雲音視頻介紹 騰訊雲音視頻服務(Cloud Tencent Real-Time Communica…

    編程 2025-04-29
  • Java Milvus SearchParam withoutFields用法介紹

    本文將詳細介紹Java Milvus SearchParam withoutFields的相關知識和用法。 一、什麼是Java Milvus SearchParam without…

    編程 2025-04-29
  • Java 8中某一周的周一

    Java 8是Java語言中的一個版本,於2014年3月18日發布。本文將從多個方面對Java 8中某一周的周一進行詳細的闡述。 一、數組處理 Java 8新特性之一是Stream…

    編程 2025-04-29
  • Python中讀入csv文件數據的方法用法介紹

    csv是一種常見的數據格式,通常用於存儲小型數據集。Python作為一種廣泛流行的編程語言,內置了許多操作csv文件的庫。本文將從多個方面詳細介紹Python讀入csv文件的方法。…

    編程 2025-04-29
  • Java判斷字元串是否存在多個

    本文將從以下幾個方面詳細闡述如何使用Java判斷一個字元串中是否存在多個指定字元: 一、字元串遍歷 字元串是Java編程中非常重要的一種數據類型。要判斷字元串中是否存在多個指定字元…

    編程 2025-04-29
  • 如何用Python統計列表中各數據的方差和標準差

    本文將從多個方面闡述如何使用Python統計列表中各數據的方差和標準差, 並給出詳細的代碼示例。 一、什麼是方差和標準差 方差是衡量數據變異程度的統計指標,它是每個數據值和該數據值…

    編程 2025-04-29

發表回復

登錄後才能評論