十年網(wǎng)站開發(fā)經(jīng)驗(yàn) + 多家企業(yè)客戶 + 靠譜的建站團(tuán)隊(duì)
量身定制 + 運(yùn)營(yíng)維護(hù)+專業(yè)推廣+無(wú)憂售后,網(wǎng)站問(wèn)題一站解決
這篇文章主要介紹“怎么用java線程監(jiān)控Lock接口的類”的相關(guān)知識(shí),小編通過(guò)實(shí)際案例向大家展示操作過(guò)程,操作方法簡(jiǎn)單快捷,實(shí)用性強(qiáng),希望這篇“怎么用java線程監(jiān)控Lock接口的類”文章能幫助大家解決問(wèn)題。
為科爾沁左翼等地區(qū)用戶提供了全套網(wǎng)頁(yè)設(shè)計(jì)制作服務(wù),及科爾沁左翼網(wǎng)站建設(shè)行業(yè)解決方案。主營(yíng)業(yè)務(wù)為做網(wǎng)站、網(wǎng)站制作、科爾沁左翼網(wǎng)站設(shè)計(jì),以傳統(tǒng)方式定制建設(shè)網(wǎng)站,并提供域名空間備案等一條龍服務(wù),秉承以專業(yè)、用心的態(tài)度為用戶提供真誠(chéng)的服務(wù)。我們深信只要達(dá)到每一位用戶的要求,就會(huì)得到認(rèn)可,從而選擇與我們長(zhǎng)期合作。這樣,我們也可以走得更遠(yuǎn)!
區(qū)別 | 進(jìn)程 | 線程 |
根本區(qū)別 | 作為資源分配的單位 | 調(diào)度執(zhí)行的單位 |
開銷 | 每個(gè)進(jìn)程都有獨(dú)立的代碼和數(shù)據(jù)空間(進(jìn)程上下文),進(jìn)程間的切換會(huì)有較大的開銷。切換發(fā)生在不同的內(nèi)存地址上。 | 輕量級(jí)進(jìn)程,同一類線程共享代碼和數(shù)據(jù)空間,每個(gè)線程有獨(dú)立的運(yùn)行棧,以及程序計(jì)數(shù)器。線程的切換開銷小。切換發(fā)生在同一內(nèi)存地址上。 |
內(nèi)存分配 | 每個(gè)進(jìn)程分配不同的內(nèi)存區(qū)域。 | 不會(huì)為線程分配內(nèi)存。線程使用的資源是它所屬的進(jìn)程的。 |
Thread:代理角色
實(shí)現(xiàn)Runnable接口的類:真實(shí)角色
有代理就有機(jī)會(huì)在執(zhí)行真實(shí)角色對(duì)象方法之前或之后加入額外的動(dòng)作。
Thread t=Thread.currentThread() //獲取當(dāng)前線程對(duì)象 Thread.currentThread().toString() //輸出當(dāng)前線程對(duì)象的[name,priority,group] t.getName() //獲取線程的名稱 t.setName() //修改線程的名稱 Thread t=new Thread(MyRunnable,"自定義線程名稱")
t.join() 讓線程t插隊(duì) Thread.yield() 禮讓,讓出CPU的使用權(quán)一次(從運(yùn)行態(tài)進(jìn)入就緒態(tài)) Thread.sleep()
同步代碼塊
synchronized(obj){ ... }
obj為同步對(duì)象(只能是對(duì)象),且一般選擇為共享資源的對(duì)象??梢允莟his當(dāng)前對(duì)象,也可以是其他對(duì)象。
同步方法
public synchronized ... methodName(args...){ ... }
同步方法的同步對(duì)象為this。
使用繼承Thread或者使用Runnable接口靜態(tài)代理的方式,存在如下缺點(diǎn):
沒(méi)有返回值
不支持泛型
異常必須處理,不能外拋throws。
為此可以實(shí)現(xiàn)Callable接口,重寫call()方法。
public class MyCallable implements Callable{ @Override public String call() throws Exception { String[] gentleman={"春申君","信陵君","平原君","孟嘗君"}; int index=(int) (Math.random()*3); return gentleman[index]; } } class Test{ public static void main(String[] args) throws ExecutionException, InterruptedException { MyCallable call=new MyCallable(); FutureTask task=new FutureTask<>(call); Thread t=new Thread(task); t.start(); //獲取返回值 System.out.println("春秋四公子:"+task.get()); //判斷是否執(zhí)行完成 System.out.println("任務(wù)是否執(zhí)行完成:"+task.isDone()); } }
監(jiān)控實(shí)現(xiàn)Lock接口的類。
java.util.concurrent.lock中的Lock是一個(gè)接口,它的實(shí)現(xiàn)類是一個(gè)Java類,而不是關(guān)鍵字。在線程同步中比synchronized更靈活。如果同步代碼有異常,要將unLock()放到finally中。
public class CountRunnable implements Runnable { private int count = 0; Lock lock = new ReentrantLock(); @Override public void run() { for (int i = 0; i < 10; i++) { //synchronized (this) { try { lock.lock(); count++; try { Thread.sleep(300); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(Thread.currentThread().getName() + "執(zhí)行操作:count=" + count); } finally { lock.unlock(); } } } } class Test { public static void main(String[] args) { CountRunnable cr = new CountRunnable(); Thread t1 = new Thread(cr, "A"); Thread t2 = new Thread(cr, "B"); Thread t3 = new Thread(cr, "C"); t1.start(); t2.start(); t3.start(); } }
Lock與synchronized的區(qū)別
Lock是顯式鎖,需要手動(dòng)開啟和關(guān)閉,而隱式鎖synchronized不需要。
Lock只有代碼塊鎖,而synchronized有代碼塊鎖和方法鎖。
使用Lock鎖JVM將花費(fèi)更少的時(shí)間來(lái)調(diào)度線程。有更好的性能和擴(kuò)展性(提供更多的子類)。
Lock本質(zhì)是一個(gè)臨界區(qū)鎖。
執(zhí)行Runnable任務(wù)
public class Test1 { public static void main(String[] args) { //線程池中只有一個(gè)線程 // ExecutorService pool1 = Executors.newSingleThreadExecutor(); //線程池中有固定數(shù)量的線程 ExecutorService pool1 = Executors.newFixedThreadPool(10); //線程池中的線程數(shù)是動(dòng)態(tài)改變的(按需) // ExecutorService pool1 = Executors.newCachedThreadPool(); //執(zhí)行大量任務(wù) for (int i = 0; i < 20; i++) { final int n = i; Runnable cmd = new Runnable() { @Override public void run() { System.out.println("開始執(zhí)行:" + n); try { Thread.sleep(300); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("執(zhí)行結(jié)束:" + n); } }; pool1.execute(cmd); } pool1.shutdown(); } }
執(zhí)行Callable任務(wù)
public class Test2 { public static void main(String[] args) throws ExecutionException, InterruptedException { //線程池中只有一個(gè)線程 // ExecutorService pool1 = Executors.newSingleThreadExecutor(); //線程池中有固定數(shù)量的線程 ExecutorService pool1 = Executors.newFixedThreadPool(10); //線程池中的線程數(shù)是動(dòng)態(tài)改變的(按需) // ExecutorService pool1 = Executors.newCachedThreadPool(); Listlist = new ArrayList<>(); //執(zhí)行大量任務(wù) for (int i = 0; i < 20; i++) { final int n = i; Callable task = new Callable () { @Override public Integer call() throws Exception { Thread.sleep(500); return (int) (Math.random() * 10) + 1; } }; Future f = pool1.submit(task); list.add(f); //先把任務(wù)都分發(fā)出去 // System.out.println(f.get()); //要等到每個(gè)線程執(zhí)行結(jié)束才得到返回值,效率較低 } System.out.println("分發(fā)異步執(zhí)行"); for (Future f : list) { //最后再收集返回結(jié)果 System.out.println(f.get()); } System.out.println("獲得最終執(zhí)行結(jié)果"); pool1.shutdown(); } }
ThreadLocal經(jīng)常應(yīng)用在數(shù)據(jù)庫(kù)連接和session管理上。
關(guān)于“怎么用java線程監(jiān)控Lock接口的類”的內(nèi)容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業(yè)相關(guān)的知識(shí),可以關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道,小編每天都會(huì)為大家更新不同的知識(shí)點(diǎn)。