日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

command对象提供的3个execute方法是_并发面试题:java中有几种方法可以实现一个线程?...

發布時間:2023/12/10 编程问答 36 豆豆
生活随笔 收集整理的這篇文章主要介紹了 command对象提供的3个execute方法是_并发面试题:java中有几种方法可以实现一个线程?... 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

創建并啟動線程的6種方式

  • 繼承Thread類創建線程
  • 實現Runnable接口創建線程
  • 使用Callable和FutureTask創建線程
  • 使用線程池,例如用Executor框架
  • Spring實現多線程(底層是線程池)
  • 定時器Timer (底層封裝了一個TimerThread對象)

1、繼承Thread類創建線程

1.1繼承Thread類方式創建線程的實現步驟:

步驟:

1) 定義一個類A繼承于java.lang.Thread類

2)在A類中覆蓋Thread類中的run方法

3)我們在run方法中編寫需要執行的操作---->run方法里的,線程執行體

4)在main方法(線程)中,創建線程對象,并啟動線程

  • 創建線程類對象: A類 a = new A類();
  • 調用線程對象的start方法: a.start();//啟動一個線程

注意:千萬不要調用run方法,如果調用run方法好比是對象調用方法,依然還是只有一個線程,并沒有開啟新的線程。

1.2需求:使用兩個線程實現邊聽歌邊打游戲

實現代碼:

//音樂線程 public class MusicThread { public static void main(String[] args) { //創建游戲線程對象 GameThread game = new GameThread(); //啟動游戲線程 game.start(); while(true){ System.out.println(Thread.currentThread().getName()+"聽音樂!"); } } } //游戲線程 class GameThread extends Thread{ @Override public void run() { while (true) { System.out.println(Thread.currentThread().getName()+"打游戲!"); } } }

注意:有的小伙伴可能覺得音樂線程沒有啟動,在這里其實音樂線程已經啟動起來了,而啟動音樂線程的對象就是我們的JVM,此處main方法其實啟動的時候會創建一個主線程去執行main方法,所以我在這里使用主線程作為了我的音樂線程。

2、實現Runnable接口創建線程

2.1實現Runnable接口方式創建線程的實現步驟:

1)定義一個類A實現于java.lang.Runnable接口,注意A類不是線程類。 2)在A類中覆蓋Runnable接口中的run方法。 3) 我們在run方法中編寫需要執行的操作---->run方法里的,線程執行體。 4)在main方法(線程)中,創建線程對象,并啟動線程。

  • 創建線程類對象: Thread t = new Thread(new A());
  • 調用線程對象的start方法: t.start();

2.2需求:使用兩個線程實現邊聽歌邊打游戲

實現代碼:

//音樂線程 public class MusicThread { public static void main(String[] args) { //創建游戲線程對象 Thread game = new Thread(new Game()); //啟動游戲線程 game.start(); while(true){ System.out.println(Thread.currentThread().getName()+"聽音樂!"); } } }//游戲 class Game implements Runnable{ @Override public void run() { while (true) { System.out.println(Thread.currentThread().getName()+"打游戲!"); } } }

2.3 繼承方式和實現方式的區別

1)繼承方式是一個類繼承了Thread后成為線程類的子類,實現方式是一個類實現Runnable接口,但是這個類不是線程類,因為該類沒有start等方法。

2)啟動的時候繼承方式直接調用自己的start方法,實現方式是借助了Thread中的start方法啟動的,自身沒有start方法。

3)繼承方式調用的run方法是通過方法覆蓋,通過繼承方式實現的,運行的時候先找子類,沒有最后才運行父類的run方法。實現方式是執行Thread的run方法,而Thread中的run方法調用了實現類中的run方法,使用過組合關系的方法調用實現的。

3、實現 Callable 接口

3.1使用Callable和FutureTask創建線程的實現步驟:

1)定義一個Callable接口的實現類

2)創建Callable實現類對象傳遞給FutureTask構造器

3)將FutureTask對象傳遞給Thread構造器

4)Thread對象調用start方法啟動線程

5)通過FutureTask對象的get方法獲取線程運行的結果

注意: Future就是對于具體的Runnable或者Callable任務的執行結果進行取消、查詢是否完成、獲取結果。必要時可以通過get方法獲取執行結果,該方法會阻塞直到任務返回結果。

使用場景:使用多線程計算結果并返回該結果。

3.2需求:使用2個線程異步計算1-1000,000內之和

實現代碼:

public class CallableDemo { public static void main(String[] args) throws Exception { //1.創建并啟動線程 Callable<Integer> call1 = new CallableImpl(0, 50000); Callable<Integer> call2 = new CallableImpl(50001, 100000);FutureTask<Integer> f1 = new FutureTask<>(call1); FutureTask<Integer> f2 = new FutureTask<>(call2);new Thread(f1).start(); new Thread(f2).start(); //2.獲取每一個線程的結果 int ret1 = f1.get(); int ret2 = f2.get(); int ret= ret1+ret2; System.out.println(ret); } } class CallableImpl implements Callable<Integer>{private int min; private int max;public CallableImpl(int min, int max) { this.min = min; this.max = max; }@Override public Integer call() throws Exception { int sum = 0; for (int i = min; i <= max; i++) { sum+=i; } return sum; } }

3.3Callable和Runnable的區別如下:

Callable定義的方法是call,而Runnable定義的方法是run。

Callable的call方法可以有返回值,而Runnable的run方法不能有返回值。

Callable的call方法可拋出異常,而Runnable的run方法不能拋出異常。

注意:

FutureTask為Runnable的實現類

FutureTask可以視為一個閉鎖(門閂),因為只有當線程運行完才會出現結果。

4、使用線程池

線程池,顧名思義就是一個池子里面放了很多的線程,我們用就將線程從里面拿出來,使用完畢就放回去池子中。設計和數據庫連接池相似,存在靜態工廠方法用于創建各種線程池。

操作步驟:

1)使用Executors工具類中的靜態工廠方法用于創建線程池 newFixedThreadPool:創建可重用且固定線程數的線程池, newScheduledThreadPool:創建一個可延遲執行或定期執行的線程池 newCachedThreadPool:創建可緩存的線程池

2)使用execute方法啟動線程

3)使用shutdown方法等待提交的任務執行完成并后關閉線程。

代碼演示如下:

public class Demo4 {public static void main(String[] args) {Executor executor = Executors.newFixedThreadPool(5);executor.execute(new Runnable() {@Overridepublic void run() {System.out.println(Thread.currentThread().getName());}});((ExecutorService) executor).shutdown();} }

5、Spring實現多線程

在Spring3之后,Spring引入了對多線程的支持,如果你使用的版本在3.1以前,應該還是需要通過傳統的方式來實現多線程的。從Spring3同時也是新增了Java的配置方式,而且Java配置方式也逐漸成為主流的Spring的配置方式。

代碼演示如下:

導入的包:

<dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter</artifactId><version>2.1.0.RELEASE</version></dependency> </dependencies>

配置類:

@Configuration @ComponentScan("cn.wolfcode") @EnableAsync //允許使用異步任務 public class SpringConfig {}

服務類:

@Service public class SpringService {@Async // 這里進行標注為異步任務,在執行此方法的時候,會單獨開啟線程來執行public void dowork1() {for (int i = 0; i < 10; i++) {System.out.println(Thread.currentThread().getName() + "-->" + i);}}@Asyncpublic void dowork2() {for (int i = 0; i < 10; i++) {System.out.println(Thread.currentThread().getName() + "-->" + i);}} }

測試類:

public class SpringThreadDemo {public static void main(String[] args) {AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(SpringConfig.class);SpringService bean = context.getBean(SpringService.class);bean.dowork1();bean.dowork2();} }

注意:此時會出現一個DEBUG信息

在這里DEBUG信息不是什么錯誤,不會影響代碼的正常運行,其實可以不用管的,但是為什么出現這個問題呢?

Spring的定時任務調度器會通過BeanFactory.getBean的方法來嘗試獲取一個注冊過的TaskExecutor對象來做任務調度,獲取不到TaskExecutor對象再嘗試找ScheduledExecutorService 對象,都找不到就報DEBUG信息。報錯之后就找自己本身默認的scheduler定時器對象,這個舉動其實是做一個提醒作用,所以如果沒有強迫癥可以不用管它。

解決Spring使用多線程的報錯信息

強迫癥患者想要解決怎么辦,三種方式:

  • 在log4j文件中加入log4j.logger.org.springframework.scheduling = INFO(治標不治本)
  • 在本配置文件或者配置類中設置一個bean
  • 配置類實現AsyncConfigurer接口并覆蓋其getAsyncExecutor方法

6 定時器

嚴格來說定時器(Timer)不是線程,他只是調度線程的一種工具,它里面封裝了一個線程,所以我們可以使用定時器來使用線程。

操作步驟:

1)創建Timer 對象

2)調用schedule方法

3)傳入TimerTask子類對象

代碼演示如下:

Timer timer = new Timer(); timer.schedule(new TimerTask() {@Overridepublic void run() {for (int i = 0; i < 10; i++) {System.out.println(Thread.currentThread().getName() + "-->" + i);}} }, 100, 100);

?文源網絡,僅供學習之用,如有侵權,聯系刪除。

我整理了一套學習資料,涵蓋Java虛擬機、spring框架、Java線程、數據結構、設計模式等等,免費提供給熱愛Java的同學! 戳我主頁查看獲取方式。

總結

以上是生活随笔為你收集整理的command对象提供的3个execute方法是_并发面试题:java中有几种方法可以实现一个线程?...的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。