A. java線程池怎麼實現的
多線程技術主要解決處理器單元內多個線程執行的問題,它可以顯著減少處理器單元的閑置時間,增加處理器單元的吞吐能力。
假設一個伺服器完成一項任務所需時間為:T1 創建線程時間,T2 在線程中執行任務的時間,T3 銷毀線程時間。
如果:T1 + T3 遠大於 T2,則可以採用線程池,以提高伺服器性能。
一個線程池包括以下四個基本組成部分:
1、線程池管理器(ThreadPool):用於創建並管理線程池,包括 創建線程池,銷毀線程池,添加新任務;
2、工作線程(PoolWorker):線程池中線程,在沒有任務時處於等待狀態,可以循環的執行任務;
3、任務介面(Task):每個任務必須實現的介面,以供工作線程調度任務的執行,它主要規定了任務的入口,任務執行完後的收尾工作,任務的執行狀態等;
4、任務隊列(taskQueue):用於存放沒有處理的任務。提供一種緩沖機制。
線程池技術正是關注如何縮短或調整T1,T3時間的技術,從而提高伺服器程序性能的。它把T1,T3分別安排在伺服器程序的啟動和結束的時間段或者一些空閑的時間段,這樣在伺服器程序處理客戶請求時,不會有T1,T3的開銷了。
線程池不僅調整T1,T3產生的時間段,而且它還顯著減少了創建線程的數目,看一個例子:
假設一個伺服器一天要處理50000個請求,並且每個請求需要一個單獨的線程完成。在線程池中,線程數一般是固定的,所以產生線程總數不會超過線程池中線程的數目,而如果伺服器不利用線程池來處理這些請求則線程總數為50000。一般線程池大小是遠小於50000。所以利用線程池的伺服器程序不會為了創建50000而在處理請求時浪費時間,從而提高效率。
代碼實現中並沒有實現任務介面,而是把Runnable對象加入到線程池管理器(ThreadPool),然後剩下的事情就由線程池管理器(ThreadPool)來完成了
packagemine.util.thread;
importjava.util.LinkedList;
importjava.util.List;
/**
*線程池類,線程管理器:創建線程,執行任務,銷毀線程,獲取線程基本信息
*/
publicfinalclassThreadPool{
//線程池中默認線程的個數為5
privatestaticintworker_num=5;
//工作線程
privateWorkThread[]workThrads;
//未處理的任務
_task=0;
//任務隊列,作為一個緩沖,List線程不安全
privateList<Runnable>taskQueue=newLinkedList<Runnable>();
;
//創建具有默認線程個數的線程池
privateThreadPool(){
this(5);
}
//創建線程池,worker_num為線程池中工作線程的個數
privateThreadPool(intworker_num){
ThreadPool.worker_num=worker_num;
workThrads=newWorkThread[worker_num];
for(inti=0;i<worker_num;i++){
workThrads[i]=newWorkThread();
workThrads[i].start();//開啟線程池中的線程
}
}
//單態模式,獲得一個默認線程個數的線程池
(){
returngetThreadPool(ThreadPool.worker_num);
}
//單態模式,獲得一個指定線程個數的線程池,worker_num(>0)為線程池中工作線程的個數
//worker_num<=0創建默認的工作線程個數
(intworker_num1){
if(worker_num1<=0)
worker_num1=ThreadPool.worker_num;
if(threadPool==null)
threadPool=newThreadPool(worker_num1);
returnthreadPool;
}
//執行任務,其實只是把任務加入任務隊列,什麼時候執行有線程池管理器覺定
publicvoidexecute(Runnabletask){
synchronized(taskQueue){
taskQueue.add(task);
taskQueue.notify();
}
}
//批量執行任務,其實只是把任務加入任務隊列,什麼時候執行有線程池管理器覺定
publicvoidexecute(Runnable[]task){
synchronized(taskQueue){
for(Runnablet:task)
taskQueue.add(t);
taskQueue.notify();
}
}
//批量執行任務,其實只是把任務加入任務隊列,什麼時候執行有線程池管理器覺定
publicvoidexecute(List<Runnable>task){
synchronized(taskQueue){
for(Runnablet:task)
taskQueue.add(t);
taskQueue.notify();
}
}
//銷毀線程池,該方法保證在所有任務都完成的情況下才銷毀所有線程,否則等待任務完成才銷毀
publicvoiddestroy(){
while(!taskQueue.isEmpty()){//如果還有任務沒執行完成,就先睡會吧
try{
Thread.sleep(10);
}catch(InterruptedExceptione){
e.printStackTrace();
}
}
//工作線程停止工作,且置為null
for(inti=0;i<worker_num;i++){
workThrads[i].stopWorker();
workThrads[i]=null;
}
threadPool=null;
taskQueue.clear();//清空任務隊列
}
//返回工作線程的個數
publicintgetWorkThreadNumber(){
returnworker_num;
}
//返回已完成任務的個數,這里的已完成是只出了任務隊列的任務個數,可能該任務並沒有實際執行完成
(){
returnfinished_task;
}
//返回任務隊列的長度,即還沒處理的任務個數
publicintgetWaitTasknumber(){
returntaskQueue.size();
}
//覆蓋toString方法,返回線程池信息:工作線程個數和已完成任務個數
@Override
publicStringtoString(){
return"WorkThreadnumber:"+worker_num+"finishedtasknumber:"
+finished_task+"waittasknumber:"+getWaitTasknumber();
}
/**
*內部類,工作線程
*/
{
//該工作線程是否有效,用於結束該工作線程
privatebooleanisRunning=true;
/*
*關鍵所在啊,如果任務隊列不空,則取出任務執行,若任務隊列空,則等待
*/
@Override
publicvoidrun(){
Runnabler=null;
while(isRunning){//注意,若線程無效則自然結束run方法,該線程就沒用了
synchronized(taskQueue){
while(isRunning&&taskQueue.isEmpty()){//隊列為空
try{
taskQueue.wait(20);
}catch(InterruptedExceptione){
e.printStackTrace();
}
}
if(!taskQueue.isEmpty())
r=taskQueue.remove(0);//取出任務
}
if(r!=null){
r.run();//執行任務
}
finished_task++;
r=null;
}
}
//停止工作,讓該線程自然執行完run方法,自然結束
publicvoidstopWorker(){
isRunning=false;
}
}
}
B. java多線程實現 5秒一次列印當前時間
package com.test;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
public class PrnCurrentTime implements Runnable {
public void run()
{
while(true){
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
Date now = new Date();
DateFormat df = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
System.out.println(df.format(now));
}
}
/**
* @ args
*/
public static void main(String[] args) {
PrnCurrentTime p = new PrnCurrentTime();
new Thread(p).start();
}
}
C. java多線程框架有哪些
Java多線程框架主要有以下幾種:
1. Java原生線程框架
Java語言本身提供了多線程的原生支持,通過java.lang.Thread類以及java.util.concurrent包中的一系列類來實現多線程編程。其中,Thread類是Java中最基本的線程類,可以通過繼承Thread類或使用實現Runnable介面的方式創建線程。此外,java.util.concurrent包提供了一系列支持並發編程的工具類,如ExecutorService、CountDownLatch等。
2. Spring框架中的多線程支持
Spring框架提供了對多線程編程的良好支持,主要體現在Spring的任務調度框架中。通過Spring的TaskExecutor介面,可以方便地進行任務調度和線程池管理。此外,Spring還提供了註解驅動的非同步方法執行,通過@Async註解可以輕松地實現非同步處理。
3. Java並發包java.util.concurrent
java.util.concurrent包是Java標准庫中一個重要的並發工具包,提供了多種並發編程的工具類。其中,線程池相關的類如ThreadPoolExecutor、ScheledThreadPoolExecutor等被廣泛應用於多線程編程中。此外,該包還提供了並發集合類,可以有效地處理並發訪問問題。
4. Java多線程框架Apache MINA和Netty
Apache MINA和Netty是Java中常用的網路編程框架,它們也提供了對多線程編程的支持。這兩個框架都基於非同步事件驅動模型,可以有效地處理高並發網路連接和數據傳輸。其中,Netty是一個高性能的非同步事件驅動的網路應用框架,廣泛應用於開發網路服務和分布式系統。
以上這些Java多線程框架各有特點,適用於不同的應用場景。開發者可以根據具體需求選擇合適的框架來實現多線程編程。
D. 什麼是java線程池
找的資料,你看一下吧:
多線程技術主要解決處理器單元內多個線程執行的問題,它可以顯著減少處理器單元的閑置時間,增加處理器單元的吞吐能力。
假設一個伺服器完成一項任務所需時間為:T1 創建線程時間,T2 在線程中執行任務的時間,T3 銷毀線程時間。
如果:T1 + T3 遠大於 T2,則可以採用線程池,以提高伺服器性能。
一個線程池包括以下四個基本組成部分:
1、線程池管理器(ThreadPool):用於創建並管理線程池,包括 創建線程池,銷毀線程池,添加新任務;
2、工作線程(PoolWorker):線程池中線程,在沒有任務時處於等待狀態,可以循環的執行任務;
3、任務介面(Task):每個任務必須實現的介面,以供工作線程調度任務的執行,它主要規定了任務的入口,任務執行完後的收尾工作,任務的執行狀態等;
4、任務隊列(taskQueue):用於存放沒有處理的任務。提供一種緩沖機制。
線程池技術正是關注如何縮短或調整T1,T3時間的技術,從而提高伺服器程序性能的。它把T1,T3分別安排在伺服器程序的啟動和結束的時間段或者一些空閑的時間段,這樣在伺服器程序處理客戶請求時,不會有T1,T3的開銷了。
線程池不僅調整T1,T3產生的時間段,而且它還顯著減少了創建線程的數目,看一個例子:
假設一個伺服器一天要處理50000個請求,並且每個請求需要一個單獨的線程完成。在線程池中,線程數一般是固定的,所以產生線程總數不會超過線程池中線程的數目,而如果伺服器不利用線程池來處理這些請求則線程總數為50000。一般線程池大小是遠小於50000。所以利用線程池的伺服器程序不會為了創建50000而在處理請求時浪費時間,從而提高效率。
E. 淺談Java多線程的同步問題
多線程的同步依靠的是對象鎖機制 synchronized關鍵字的背後就是利用了封鎖來實現對共享資源的互斥訪問
下面以一個簡單的實例來進行對比分析 實例要完成的工作非常簡單 就是創建 個線程 每個線程都列印從 到 這 個數字 我們希望線程之間不會出現交叉亂序列印 而是順序地列印
先來看第一段代碼 這里我們在run()方法中加入了synchronized關鍵字 希望能對run方法進行互斥訪問 但結果並不如我們希望那樣 這是因為這里synchronized鎖住的是this對象 即當前運行線程對象本身 代碼中創建了 個線程 而每個線程都持有this對象的對象鎖 這不能實現線程的同步
代碼 package vista; class MyThread implements java lang Runnable { private int threadId;
public MyThread(int id) { this threadId = id; }
@Override public synchronized void run() { for (int i = ; i < ; ++i) { System out println( Thread ID: + this threadId + : + i); } } }
public class ThreadDemo { /** * @param args * @throws InterruptedException */ public static void main(String[] args) throws InterruptedException { for (int i = ; i < ; ++i) { new Thread(new MyThread(i)) start(); Thread sleep( ); } } }
從上述代碼段可以得知 要想實現線程的同步 則這些線程必須去競爭一個唯一的共享的對象鎖
基於這種思想 我們將第一段代碼修改如下所示 在創建啟動線程之前 先創建一個線程之間競爭使用的Object對象 然後將這個Object對象的引用傳遞給每一個線程對象的lock成員變數 這樣一來 每個線程的lock成員都指向同一個Object對象 我們在run方法中 對lock對象使用synchronzied塊進行局部封鎖 這樣就可以讓線程去競爭這個唯一的共享的對象鎖 從而實現同步
代碼 package vista;
class MyThread implements java lang Runnable { private int threadId; private Object lock;
public MyThread(int id Object obj) { this threadId = id; this lock = obj; }
@Override public void run() { synchronized (lock) { for (int i = ; i < ; ++i) { System out println( Thread ID: + this threadId + : + i); } } } }
public class ThreadDemo { /** * @param args * @throws InterruptedException */ public static void main(String[] args) throws InterruptedException { Object obj = new Object(); for (int i = ; i < ; ++i) { new Thread(new MyThread(i obj)) start(); Thread sleep( ); } } }
從第二段代碼可知 同步的關鍵是多個線程對象競爭同一個共享資源即可 上面的代碼中是通過外部創建共享資源 然後傳遞到線程中來實現 我們也可以利用類成員變數被所有類的實例所共享這一特性 因此可以將lock用靜態成員對象來實現 代碼如下所示
代碼 package vista;
class MyThread implements java lang Runnable { private int threadId; private static Object lock = new Object();
public MyThread(int id) { this threadId = id; }
@Override public void run() { synchronized (lock) { for (int i = ; i < ; ++i) { System out println( Thread ID: + this threadId + : + i); } } } }
public class ThreadDemo { /** * @param args * @throws InterruptedException */ public static void main(String[] args) throws InterruptedException { for (int i = ; i < ; ++i) { new Thread(new MyThread(i)) start(); Thread sleep( ); } } }
再來看第一段代碼 實例方法中加入sychronized關鍵字封鎖的是this對象本身 而在靜態方法中加入sychronized關鍵字封鎖的就是類本身 靜態方法是所有類實例對象所共享的 因此線程對象在訪問此靜態方法時是互斥訪問的 從而可以實現線程的同步 代碼如下所示
代碼 package vista;
class MyThread implements java lang Runnable { private int threadId;
public MyThread(int id) { this threadId = id; }
@Override public void run() { taskHandler(this threadId); }
private static synchronized void taskHandler(int threadId) { for (int i = ; i < ; ++i) { System out println( Thread ID: + threadId + : + i); } } }
lishixin/Article/program/Java/gj/201311/27441