自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

并發(fā)編程把我整的是服服氣氣的了

開(kāi)發(fā) 前端
阿粉因?yàn)樵瓉?lái)的編程習(xí)慣,已經(jīng)很久沒(méi)有去考慮并發(fā)的問(wèn)題了,結(jié)果之前在面試的問(wèn)題就回答的不是很完善,而阿粉也用心學(xué)習(xí)了并發(fā)編程這一塊的所有內(nèi)容,一起來(lái)分享給大家。

 阿粉因?yàn)樵瓉?lái)的編程習(xí)慣,已經(jīng)很久沒(méi)有去考慮并發(fā)的問(wèn)題了,結(jié)果之前在面試的問(wèn)題就回答的不是很完善,而阿粉也用心學(xué)習(xí)了并發(fā)編程這一塊的所有內(nèi)容,一起來(lái)分享給大家。

[[356708]]

為什么需要并發(fā)編程因?yàn)楝F(xiàn)在的CPU我們大家也都知道,什么幾核幾線程,各種各樣,而我們并發(fā)編程的目的是為了讓程序運(yùn)行得更快,這里的更快說(shuō)的并不是讓我們無(wú)限制啟動(dòng)更多的線程就能讓程序進(jìn)行最大可能的并發(fā)操作,但是我們?cè)谶M(jìn)行并發(fā)編程的時(shí)候,很容易遇到很多的問(wèn)題,比如說(shuō)死鎖問(wèn)題,再比如說(shuō)上下文的切換的問(wèn)題,這都是問(wèn)題所在。

實(shí)現(xiàn)多線程的幾種方式,面試中最簡(jiǎn)單的題目

說(shuō)起來(lái)這個(gè)面試題,很多回答都一樣,

  • 繼承Thread類
  • 實(shí)現(xiàn)Runnable接口
  • 使用線程池

這是很多面試者回答的時(shí)候總是回答這三個(gè),但是實(shí)際上,實(shí)現(xiàn)多線程的方式也不限于這幾種方式,還有比如說(shuō)帶返回值的線程實(shí)現(xiàn),定時(shí)器實(shí)現(xiàn),內(nèi)部類實(shí)現(xiàn),這些方式都是可以實(shí)現(xiàn)多線程的。那我們今天就先來(lái)把這些不常用的方式來(lái)梳理一下。

使用匿名內(nèi)部類的方式實(shí)現(xiàn)多線程

其實(shí)說(shuō)實(shí)話,這匿名內(nèi)部類的方式也不能算是一種新的實(shí)現(xiàn)方式,只不過(guò)是把這個(gè)實(shí)現(xiàn)方式放到了匿名類里面了,實(shí)現(xiàn)的總體內(nèi)部還是使用的繼承 Thread和實(shí)現(xiàn)Runnable接口。

案例實(shí)現(xiàn):

 

  1. public class TestClass { 
  2.     public static void main(String[] args) { 
  3.         // 基于子類的方式 
  4.         new Thread() { 
  5.             @Override 
  6.             public void run() { 
  7.                 while (true) { 
  8.                     printThreadInfo(); 
  9.                 } 
  10.             } 
  11.         }.start(); 
  12.  
  13.         // 基于接口的實(shí)現(xiàn) 
  14.         new Thread(new Runnable() { 
  15.             @Override 
  16.             public void run() { 
  17.                 while (true) { 
  18.                     printThreadInfo(); 
  19.                 } 
  20.             } 
  21.         }).start(); 
  22.     } 
  23.     private static void printThreadInfo() { 
  24.         System.out.println("當(dāng)前運(yùn)行的線程名為: " + Thread.currentThread().getName()); 
  25.         try { 
  26.             Thread.sleep(1000); 
  27.         } catch (Exception e) { 
  28.             throw new RuntimeException(e); 
  29.         } 
  30.     } 
  31.  
  32. 實(shí)現(xiàn)結(jié)果: 
  33.  
  34. 當(dāng)前運(yùn)行的線程名為:Thread-1 
  35. 當(dāng)前運(yùn)行的線程名為:Thread-0 
  36. 當(dāng)前運(yùn)行的線程名為:Thread-1 
  37. 當(dāng)前運(yùn)行的線程名為:Thread-0 
  38. 當(dāng)前運(yùn)行的線程名為:Thread-1 
  39. 當(dāng)前運(yùn)行的線程名為:Thread-0 
  40. 當(dāng)前運(yùn)行的線程名為:Thread-0 
  41. 當(dāng)前運(yùn)行的線程名為:Thread-1 
  42. 當(dāng)前運(yùn)行的線程名為:Thread-1 
  43. 當(dāng)前運(yùn)行的線程名為:Thread-0 
  44. 當(dāng)前運(yùn)行的線程名為:Thread-0 
  45. 當(dāng)前運(yùn)行的線程名為:Thread-1 

其實(shí)對(duì)于上述手段,大家也肯定都會(huì),那么我們就說(shuō)說(shuō)這個(gè)定時(shí)器實(shí)現(xiàn)方式,這個(gè)方式實(shí)際上是也是大家經(jīng)常會(huì)使用的一種方式,因?yàn)槲覀兒芏鄷r(shí)候都需要在我們不在的情況下進(jìn)行一些操作,比如說(shuō),每天晚上對(duì)系統(tǒng)進(jìn)行一下當(dāng)天的統(tǒng)計(jì)操作什么的。

使用定時(shí)器實(shí)現(xiàn)

 

  1. public class TestClass { 
  2.     private static final SimpleDateFormat dateFormat = 
  3.             new SimpleDateFormat("yyyy-MM-dd hh:mm:ss"); 
  4.  
  5.     public static void main(String[] args) throws Exception { 
  6.         // 創(chuàng)建定時(shí)器 
  7.         Timer timer = new Timer(); 
  8.  
  9.         // 提交計(jì)劃任務(wù) 
  10.         timer.schedule(new TimerTask() { 
  11.             @Override 
  12.             public void run() { 
  13.                 System.out.println("定時(shí)任務(wù)執(zhí)行了..."); 
  14.             } 
  15.         }, dateFormat.parse("2020-12-08 20:30:00")); 
  16.     } 
  17.  
  18. 這段代碼大家可以復(fù)制一下,在你設(shè)定好的時(shí)間內(nèi)進(jìn)行執(zhí)行 

關(guān)于多線程的實(shí)現(xiàn)方式,阿粉就給大家講述到這里,畢竟這個(gè)東西在你使用的時(shí)候,一定是活學(xué)活用的,不是一成不變的,需要你看自己的需求來(lái)弄。

接下來(lái)我們就先從并發(fā)編程的線程安全性開(kāi)始入手,接下來(lái)阿粉也會(huì)繼續(xù)給大家更新關(guān)于并發(fā)編程的各種技術(shù)內(nèi)容,讓大家能夠盡快的掌握好這個(gè)線程安全的問(wèn)題,

線程的安全性操作

其實(shí)對(duì)于一個(gè)對(duì)象來(lái)說(shuō),他是否是線程安全的,完全取決于他是否被多個(gè)線程去訪問(wèn),而如果要讓我們的對(duì)象是線程安全的話,那么我們一定要采取一些方式,而方式都有哪些呢?

  • 同步機(jī)制
  • 加鎖機(jī)制

也就是大家所了解的同步 Synchronized 和加鎖的機(jī)制。還有就是使用Volatile類型的變量。

也就是說(shuō),如果多個(gè)線程去訪問(wèn)同一個(gè)可變的狀態(tài)的變量的時(shí)候,沒(méi)有使用合適的同步,那么程序相對(duì)來(lái)說(shuō)就會(huì)出現(xiàn)錯(cuò)誤,而解決方式也有好幾種,

  • 比如說(shuō)不在線程之前共享這個(gè)變量
  • 將狀態(tài)變量修改成為不可變的的變量
  • 在訪問(wèn)狀態(tài)變量的時(shí)候使用同步

而阿粉之前也看過(guò)一個(gè)圖片,就是說(shuō)他從字節(jié)碼的角度去分析了線程不安全的操作,看下圖

 

 

 

 

用一個(gè)最簡(jiǎn)單的案例給大家講解Synchronized,我們手動(dòng)實(shí)現(xiàn)一個(gè)線程然后遞減,每次輸出這個(gè)變量,最終看效果圖

 

  1. public class TestClass implements Runnable{ 
  2.     int i = 100; 
  3.  
  4.     @Override 
  5.     public void run() { 
  6.         // TODO Auto-generated method stub 
  7.         while(true) { 
  8.             if(i>0) { 
  9.                 try { 
  10.                     Thread.sleep(10);//為了讓安全問(wèn)題明顯,我們讓線程執(zhí)行的時(shí)間變長(zhǎng),故睡眠10毫秒 
  11.                 } catch (InterruptedException e) { 
  12.                     // TODO Auto-generated catch block 
  13.                     e.printStackTrace(); 
  14.                 } 
  15.                 System.out.println(i); 
  16.                 i--; 
  17.             } 
  18.         } 
  19.     } 
  20.  
  21. class Test{ 
  22.     public static void main(String[] args) { 
  23.         TestClass testClass = new TestClass(); 
  24.         Thread t1 = new Thread(testClass); 
  25.         Thread t2 = new Thread(testClass); 
  26.         Thread t3 = new Thread(testClass); 
  27.         t1.start(); 
  28.         t2.start(); 
  29.         t3.start(); 
  30.     } 
  31.  

不用說(shuō)大家都知道,結(jié)果肯定是亂的一塌糊涂,有來(lái)回跳躍的,也有分段執(zhí)行的,反正就是不是從100到1的,結(jié)果大家可以把代碼拿過(guò)去使用一下自己看看。

那么我們加上Synchronized關(guān)鍵字之后呢?

 

  1. public class TestClass implements Runnable{ 
  2.     int i = 100; 
  3.     @Override 
  4.     public void run() { 
  5.         while(true) { 
  6.             synchronized (this){ 
  7.                 if(i>0) { 
  8.                     try { 
  9.                         Thread.sleep(10);//為了讓安全問(wèn)題明顯,我們讓線程執(zhí)行的時(shí)間變長(zhǎng),故睡眠10毫秒 
  10.                     } catch (InterruptedException e) { 
  11.                         e.printStackTrace(); 
  12.                     } 
  13.                     System.out.println(i); 
  14.                     i--; 
  15.                 } 
  16.             } 
  17.         } 
  18.     } 
  19.  
  20. class Test{ 
  21.     public static void main(String[] args) { 
  22.         TestClass testClass = new TestClass(); 
  23.         Thread t1 = new Thread(testClass); 
  24.         Thread t2 = new Thread(testClass); 
  25.         Thread t3 = new Thread(testClass); 
  26.         t1.start(); 
  27.         t2.start(); 
  28.         t3.start(); 
  29.     } 

大家可以去執(zhí)行一下運(yùn)行結(jié)果,順帶打印出執(zhí)行結(jié)果,是不是這次就很舒服了,終于看到自己心心念念的從100-1的內(nèi)容了,而實(shí)際上,我們只是通過(guò)加上了一個(gè)同步的關(guān)鍵字,來(lái)實(shí)現(xiàn)了線程的安全性操作,讓線程同步執(zhí)行,不再會(huì)出現(xiàn)那個(gè)不安全的行為,是不是很簡(jiǎn)單?你學(xué)會(huì)了么?

責(zé)任編輯:華軒 來(lái)源: Java極客技術(shù)
相關(guān)推薦

2020-12-09 08:27:48

并發(fā)編程編程開(kāi)發(fā)

2024-05-14 08:20:59

線程CPU場(chǎng)景

2020-03-09 09:13:40

HTTPSTCP網(wǎng)絡(luò)協(xié)議

2019-09-27 09:13:55

Redis內(nèi)存機(jī)制

2022-02-07 20:36:12

網(wǎng)絡(luò)NASIP網(wǎng)段

2019-06-17 08:21:06

RPC框架服務(wù)

2024-01-04 14:16:05

騰訊紅黑樹(shù)Socket

2014-06-27 18:22:19

2022-05-20 08:30:55

TOP命令Linux

2013-06-17 11:21:27

2021-12-03 11:57:27

代碼##語(yǔ)言

2020-04-14 10:06:20

微服務(wù)Netflix語(yǔ)言

2012-07-25 09:15:16

盜版者客戶

2020-12-09 11:38:16

數(shù)據(jù)庫(kù)測(cè)試環(huán)境

2021-09-13 08:41:52

職場(chǎng)互聯(lián)網(wǎng)自閉

2015-12-14 09:39:48

編程經(jīng)驗(yàn)工作

2011-07-11 10:34:40

編程技巧蘋果

2013-01-10 10:05:29

編程面向?qū)ο缶幊?/a>

2011-10-17 09:50:38

編程

2022-07-30 12:24:55

智能圍巾傳感器心率
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)