java自定義線程池池,線程池使用及自定義線程池

一 案例引申

編寫代碼同時只允許五個線程并發訪問(以下文的函數為例子)

private static void method() {

System.out.println("ThreadName" + Thread.currentThread().getName() + "進來了");

Thread.sleep(2000);

System.out.println("ThreadName" + Thread.currentThread().getName() + "出去了");

}

思考:

1 若果使用 synchronized的話避免了并發安全問題,但是不滿足題目的要求,因為題目要求一次讓五個線程訪問,使用鎖的時候一次只能訪問一個。

2 解決思路:使用信號量或者使用線程池

二 信號量的簡單使用(了解)

package ThreadPool;

import java.util.concurrent.*;

import java.util.concurrent.atomic.AtomicInteger;

/**

* Create by SunnyDay on 2018/11/27

*/

public class ThreadPoolDemo {

//信號量 Doug Lea 大牛寫的(concurrent并發包下面的東西都是他寫的) 參數控制并發線程的個數

private static Semaphore semaphore = new Semaphore(5);

public static void main(String[] args) {

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

new Thread(new Runnable() {

@Override

public void run() {

try {

method();

} catch (InterruptedException e) {

}

}

}).start();

}

private static void method() throws InterruptedException {

// 首先獲取一把鎖

semaphore.acquire();

System.out.println("ThreadName" + Thread.currentThread().getName() + "進來了");

Thread.sleep(2000);

System.out.println("ThreadName" + Thread.currentThread().getName() + "出去了");

// 釋放鎖

semaphore.release();

}

三 使用線程池解決(了解)

package ThreadPool;

import java.util.concurrent.Executor;

import java.util.concurrent.Executors;

/**

* Create by SunnyDay on 2018/11/27

* 使用線程池解決

*/

public class ThreadPool {

/**

* java 提供了線程池的創建工具類( Executors),

* 我們可以通過工具類創建不同的線程池

*/

private static Executor executor = Executors.newCachedThreadPool();//緩沖線程池

private static Executor executor2 = Executors.newFixedThreadPool(5);//固定線程池

private static Executor executor3 = Executors.newScheduledThreadPool(5);//計劃任務線程池

private static Executor executor4 = Executors.newSingleThreadExecutor();//單個線程池(池中只有一個線程)

public static void main(String[] args) {

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

// 線程池的簡單使用(十分簡單) 調用execute方法傳遞參數類型為runnable類型即可

executor2.execute(new Runnable() {

@Override

public void run() {

try {

method();

} catch (InterruptedException e) {

e.printStackTrace();

}

}

});

}

}

private static void method() throws InterruptedException {

System.out.println("ThreadName" + Thread.currentThread().getName() + "進來了");

Thread.sleep(2000);

System.out.println("ThreadName" + Thread.currentThread().getName() + "出去了");

}

}

四 自定義線程池

1 小發現

/**

* 查看隨便幾個個線程池的源碼:

* public static ExecutorService newCachedThreadPool() {

* return new ThreadPoolExecutor(0, Integer.MAX_VALUE,

* 60L, TimeUnit.SECONDS,

* new SynchronousQueue());

* }

*

* 發現都是對線程池類(ThreadPoolExecutor)進行了簡單的封裝(傳的參數不一致)

*/

2 ThreadPoolExecutor構造( 以6個參數的為例子)

* @param corePoolSize 核心池大小 int

* @param maximumPoolSize 最大池大小 int

* @param keepAliveTime 保活時間 long(任務完成后要銷毀的延時)

* @param unit 時間單位 決定參數3的單位,枚舉類型的時間單位

* @param workQueue 工作隊列 用于存儲任務的工作隊列(BlockingQueue接口類型)

* @param threadFactory 線程工廠 用于創建線程

*

* */

public ThreadPoolExecutor(int corePoolSize,

int maximumPoolSize,

long keepAliveTime,

TimeUnit unit,

BlockingQueue workQueue,

ThreadFactory threadFactory) {

this(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue,

threadFactory, defaultHandler);

}

3 自定義實現案例

package ThreadPool;

import java.util.concurrent.*;

import java.util.concurrent.atomic.AtomicInteger;

/**

* Create by SunnyDay on 2018/11/27

*/

public class ThreadPoolDemo {

public static void main(String[] args) {

/**手寫線程池

* @param corePoolSize 核心池大小 int

* @param maximumPoolSize 最大池大小 int

* @param keepAliveTime 保活時間 long(任務完成后要銷毀的延時)

* @param unit 時間單位 決定參數3的單位,枚舉類型的時間單位

* @param workQueue 工作隊列 用于存儲任務的工作隊列(BlockingQueue接口類型)

* @param threadFactory 線程工廠 用于創建線程

*

*線程不是越多越好,google工程師推薦 線程個數=cpu核心數+1(例如四核的開5個線程最好)

* */

// 參數任務上限

LinkedBlockingQueue blockingQueue = new LinkedBlockingQueue<>(100);

ThreadFactory threadFactory = new ThreadFactory() {

// int i = 0; 用并發安全的包裝類

AtomicInteger atomicInteger = new AtomicInteger(1);

@Override

public Thread newThread(Runnable r) {

//創建線程 吧任務傳進來

Thread thread = new Thread(r);

// 給線程起個名字

thread.setName("MyThread" + atomicInteger.getAndIncrement());

return thread;

}

};

ThreadPoolExecutor pool = new ThreadPoolExecutor(10, 10, 1, TimeUnit.SECONDS, blockingQueue, threadFactory);

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

pool.execute(new Runnable() {

@Override

public void run() {

try {

method();

} catch (InterruptedException e) {

e.printStackTrace();

}

}

});

}

}

/**

* 編寫代碼(如下文的函數)同時只允許五個線程并發訪問:

*

* 1 若果使用 synchronized的話避免了并發安全問題,但是不滿足題目的要求,

* 因為題目要求一次讓五個線程訪問,使用鎖的時候一次只能訪問一個。

* 2 解決思路:使用信號量或者使用線程池

*

* 3 自己手動封裝線程池(明白啟動策略)

*/

private static void method() throws InterruptedException {

System.out.println("ThreadName" + Thread.currentThread().getName() + "進來了");

Thread.sleep(2000);

System.out.println("ThreadName" + Thread.currentThread().getName() + "出去了");

}

}

五 線程池補充

1 啟動策略草圖

d7d41e1ae40d

image.png

2 流程圖(摘抄)

d7d41e1ae40d

image.png

六 總結

通過上面的總結相信對線程池的概念,使用,啟動策略,大致的有了一些了解,但是這些還是不夠的,想要深入了解還需我們不懈的努力探討!!!

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/541810.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/541810.shtml
英文地址,請注明出處:http://en.pswp.cn/news/541810.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

long類型20位示例_Java Long類reverseBytes()方法與示例

long類型20位示例長類reverseBytes()方法 (Long class reverseBytes() method) reverseBytes() method is available in java.lang package. reverseBytes()方法在java.lang包中可用。 reverseBytes() method is used to returns the value generated by reversing the order o…

impala和mysql語法,impala CREATE TABLE語句

CREATE TABLE語句用于在Impala中的所需數據庫中創建新表。 創建基本表涉及命名表并定義其列和每列的數據類型。語法以下是CREATE TABLE語句的語法。 這里&#xff0c;IF NOT EXISTS是一個可選的子句。 如果使用此子句&#xff0c;則只有在指定數據庫中沒有具有相同名稱的現有表…

Guava翻譯系列之EventBus

EventBus 類解析 當我們開發軟件時&#xff0c;各個對象之間的數據共享和合作是必須的。 但是這里比較難做的是 怎樣保證消息之間的傳輸高效并且減少各個模塊之間的耦合。 當組件的職責不清楚時&#xff0c;一個組件還要承擔另一個組件的職責&#xff0c;這樣的系統我們就認為是…

Java PipedOutputStream close()方法與示例

PipedOutputStream類close()方法 (PipedOutputStream Class close() method) close() method is available in java.io package. close()方法在java.io包中可用。 close() method is used to close this PipedOutputStream and free all system resources linked with this str…

Java二維數組谷電,java二維數組遍歷的2種代碼

二維數組遍歷&#xff1a;思想&#xff1a;1.先將二維數組中所有的元素拿到2.再將二維數組中每個元素進行遍歷&#xff0c;相當于就是在遍歷一個一維數組第一種方法&#xff1a;雙重for循環//遍歷二維數組public class Traverse_a_two_dimensional_array {public static void m…

【轉】MyEclipse快捷鍵大全

常用快捷鍵 -------------------------------------MyEclipse 快捷鍵1(CTRL)-------------------------------------Ctrl1 快速修復CtrlD: 刪除當前行 CtrlQ 定位到最后編輯的地方 CtrlL 定位在某行 CtrlO 快速顯示 OutLine CtrlT 快速顯示當前類的繼承結構 CtrlW 關閉當…

Java整數類的compareTo()方法和示例

整數類compareTo()方法 (Integer class compareTo() method) compareTo() method is available in java.lang package. compareTo()方法在java.lang包中可用。 compareTo() method is used to check equality or inequality for this Integer object against the given Integer…

MATLAB元胞自動機報告,元胞自動機概述與MATLAB實現

什么是元胞自動機&#xff1f;元胞自動機(cellular automata&#xff0c;CA) 是一種時間、空間、狀態都離散&#xff0c;空間相互作用和時間因果關系為局部的網格動力學模型&#xff0c;具有模擬復雜系統時空演化過程的能力。它能構建隨時間推移發生狀態轉移的系統&#xff0c;…

python(33)多進程和多線程的區別

多線程可以共享全局變量&#xff0c;多進程不能。多線程中&#xff0c;所有子線程的進程號相同&#xff1b;多進程中&#xff0c;不同的子進程進程號不同。 #!/usr/bin/python # -*- coding:utf-8 -*- import os import threading import multiprocessing count_thread 0 coun…

Java FilterInputStream reset()方法與示例

FilterInputStream類的reset()方法 (FilterInputStream Class reset() method) reset() method is available in java.io package. reset()方法在java.io包中可用。 reset() method is used to reset this FilterInputStream to the position set by the most recent call of m…

不同php文件,php-不同文件夾的不同登錄(會話)

我有一個Web服務,需要用戶登錄并創建標準$_SESSION [‘XXX’]個用戶變量.我想為應用程序創建一個“演示”,因此為它創建了另一個文件夾.相同的代碼在那里,除了數據庫以外的所有東西.問題是,當用戶登錄這兩個帳戶之一時,它可以訪問兩個帳戶.因此,如果他登錄了演示應用程序,它將使…

Java Hashtable containsValue()方法與示例

哈希表類containsValue()方法 (Hashtable Class containsValue() method) containsValue() method is available in java.util package. containsValue()方法在java.util包中可用。 containsValue() method is used to check whether this table Hashtable associated one or m…

php session redis db,php session redis 配置

具體環境&#xff1a;一臺apachephp的服務器(yum安裝remi源及配置 httpd-2.2.15 php-5.4.45)一臺redis服務器(yum安裝remi源及配置 redis-3.2.6)保證apache服務器可以訪問redis服務器的6379端口具體步驟&#xff1a;1、在apachephp服務器上安裝redis擴展點擊(此處)折疊或打開yu…

sigprocmask, sigpending, sigsuspend的用法

sigset_t set sigemptyset(&set) :清空阻塞信號集合變量 sigfillset(&set) &#xff1a;添加所有的信號到阻塞集合變量里 sigaddset(&set,SIGINT):添加單一信號到阻塞信號集合變量 sigdelset(&set,SIGINT):從阻塞信號集合變量中刪除單一信號 void handler(int …

Java Calendar getDisplayName()方法與示例

日歷類的getDisplayName()方法 (Calendar Class getDisplayName() method) getDisplayName() method is available in java.util package. getDisplayName()方法在java.util包中可用。 getDisplayName() method is used to return string denotation of the given calendar fie…

matlab dir數,DIR - matlab函數

DIR List directory.DIR directory_name lists the files in a directory. Pathnames andwildcards may be used. For example, DIR *.m lists all the M-filesin the current directory.D DIR(‘directory_name‘) returns the results in an M-by-1structure with the field…

(四)其他的說明

2019獨角獸企業重金招聘Python工程師標準>>> 關于日志&#xff0c;主要是利用aop來實現的。cn.demoframe.test.frame.service.LogAspect&#xff0c;這里在方法前做了個切面setReqReachTime&#xff0c;設置了一個請求達到時間。接下來還有個切面&#xff0c;是在co…

Java LocalDate類| 帶示例的compareTo()方法

LocalDate類compareTo()方法 (LocalDate Class compareTo() method) compareTo() method is available in java.time package. compareTo()方法在java.time包中可用。 compareTo() method is used to compare this LocalDate object to the given object. compareTo()方法用于將…

vm中linux物理內存不足解決方案

為什么80%的碼農都做不了架構師&#xff1f;>>> 之前創建的一個center os,默認是8GB&#xff0c;經過一頓折磨&#xff0c;裝jdk,tomcat,redis,mycat,nginx,mysql,hadoop...終于&#xff0c;內存不足了&#xff0c;在使用docker build某鏡像的時候。迭代懵逼了&am…

matlab7.0 6.5,任何處理matlab6.5與7.0.1的兼容問題

mdl文件在6.5里面做的&#xff0c;但是到了7.0里面卻打不開&#xff0c;下面就是相關信息&#xff1a;Warning: Unable to load model file d:\MATLAB7\work\*.mdl. Run "bdclose all; set_param(0, CharacterEncoding, Enc)" where Enc is one of windows-1252, I…