<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          JAVA創(chuàng)建線程的三種方式、創(chuàng)建線程池的四種方式

          共 7234字,需瀏覽 15分鐘

           ·

          2021-03-06 07:42

          概要:

          java創(chuàng)建線程的三種方式:

          • 繼承Thread類創(chuàng)建線程類

          • 實現(xiàn)Runnable接口

          • 通過Callable和Future創(chuàng)建線程

          java創(chuàng)建線程池的四種方式:

          • newCachedThreadPool 創(chuàng)建一個可緩存的線程池,如果線程池長度超過處理需求,可靈活回收空閑線程,若無可回收,則新建線程

          • newFixedThreadPool 創(chuàng)建一個定長線程池,可控制線程最大并發(fā)數(shù),超出的線程會在隊列中等待

          • newScheduledThreadPool 創(chuàng)建一個定長線程池,支持定時及周期性任務執(zhí)行

          • newSingleThreadExecutor 創(chuàng)建一個單線程化的線程池,它只會唯一的工作線程來執(zhí)行任務,保證所有任務按照指定順序(FIFO,LIFO,優(yōu)先級)執(zhí)行

          線程池的優(yōu)點:

          • 重用存在的線程,減少對象創(chuàng)建、消亡的開銷,性能佳

          • 可有效控制最大并發(fā)線程數(shù),提高系統(tǒng)資源的使用率,同時避免過多資源競爭,避免堵塞

          • 提供定時執(zhí)行、定期執(zhí)行、單線程、并發(fā)數(shù)控制等功能

          創(chuàng)建三種線程方式代碼

          package org.jeemp.thread;

          /**
          * @author JackRen
          * @date 2021-03-04 9:47
          * @description:
          */

          public class myThread extends Thread {

          int i = 0;
          //重寫run方法,run方法的方法體就是現(xiàn)場執(zhí)行體
          public void run(){
          for(;i<100;i++){
          System.out.println(getName()+" "+i);
          }
          }

          public static void main(String[] args){
          for(int i = 0;i< 100;i++){
          System.out.println(Thread.currentThread().getName()+" : "+i);
          if(i==20){
          new myThread().start();
          new myThread().start();
          }
          }
          }



          }
          package org.jeemp.thread;

          /**
          * @author JackRen
          * @date 2021-03-04 9:56
          * @description:
          */

          public class RunnableThread implements Runnable {
          private int i;

          @Override
          public void run() {
          for(i = 0;i <100;i++){
          System.out.println(Thread.currentThread().getName()+" "+i);
          }
          }

          public static void main(String[] args){
          for(int i = 0;i < 100;i++){
          System.out.println(Thread.currentThread().getName()+" "+i);
          if(i==20){
          RunnableThread runner= new RunnableThread();
          new Thread(runner,"新線程1").start();
          new Thread(runner,"新線程2").start();
          }
          }
          }
          }
          package org.jeemp.thread;


          import java.util.concurrent.Callable;
          import java.util.concurrent.ExecutionException;
          import java.util.concurrent.FutureTask;

          /**
          * @author JackRen
          * @date 2021-03-04 10:00
          * @description:
          */

          public class CallableThread implements Callable<Integer> {

          public static void main(String[] args) {
          CallableThread ctt = new CallableThread();
          FutureTask<Integer> ft = new FutureTask<>(ctt);
          for(int i = 0;i < 100;i++){
          System.out.println(Thread.currentThread().getName()+" 的循環(huán)變量i的值"+i);
          if(i==20){
          new Thread(ft,"有返回值的線程").start();
          }
          }
          try{
          System.out.println("子線程的返回值:"+ft.get());
          } catch (InterruptedException e){
          e.printStackTrace();
          } catch (ExecutionException e){
          e.printStackTrace();
          }

          }

          @Override
          public Integer call() throws Exception {
          int i = 0;
          for(;i<100;i++){
          System.out.println(Thread.currentThread().getName()+" "+i);
          }
          return i;
          }
          }

          三種方式對比:

          1、采用實現(xiàn)Runnable、Callable接口的方式創(chuàng)建多線程

          優(yōu)勢:線程類只是實現(xiàn)了Runnable接口或Callable接口,還可以繼承其他類。在這種方式下,多個線程可以共享同一個target對象,所以非常適合多個相同線程來處理同一份資源的情況,從而可以將CPU、代碼和數(shù)據(jù)分開,形成清晰的模型,較好地體現(xiàn)了面向?qū)ο蟮乃枷搿?/p>

          劣勢:編程稍微復雜,如果要訪問當前線程,則必須使用Thread.currentThread()方法。

          2、使用繼承Thread類的方式創(chuàng)建多線程

          優(yōu)勢:編寫簡單,如果需要訪問當前線程,則無需使用Thread.currentThread()方法,直接使用this即可獲得當前線程。

          劣勢:線程類已經(jīng)繼承了Thread類,所以不能再繼承其他父類。

          3、Runnable和Callable的區(qū)別

          (1) Callable規(guī)定(重寫)的方法是call(),Runnable規(guī)定(重寫)的方法是run()。

          (2) Callable的任務執(zhí)行后可返回值,而Runnable的任務是不能返回值的。

          (3) call方法可以拋出異常,run方法不可以。

          (4) 運行Callable任務可以拿到一個Future對象,表示異步計算的結(jié)果。它提供了檢查計算是否完成的方法,以等待計算的完成,并檢索計算的結(jié)果。通過Future對象可以了解任務執(zhí)行情況,可取消任務的執(zhí)行,還可獲取執(zhí)行結(jié)果future.get()。

          創(chuàng)建四種線程池的方式

          package org.jeemp.thread.pool;

          import java.util.concurrent.ExecutorService;
          import java.util.concurrent.Executors;
          import java.util.concurrent.ScheduledExecutorService;
          import java.util.concurrent.TimeUnit;

          /**
          * @author JackRen
          * @date 2021-03-04 13:40
          * @description:
          */

          public class ExecutorsPools {

          ExecutorService cachedThreadPool = Executors.newCachedThreadPool();
          ExecutorService fixedThreadPool = Executors.newFixedThreadPool(3);
          ScheduledExecutorService scheduledThreadPool = Executors.newScheduledThreadPool(5);
          ExecutorService singleThreadExecutor = Executors.newSingleThreadExecutor();

          /*
          * 創(chuàng)建一個可緩存線程池,如果線程池長度超過處理需要,可靈活回收空閑線程,若無可回收,則新建線程
          * 線程池為無限大,當執(zhí)行第二個任務時第一個任務已經(jīng)完成,會復用執(zhí)行第一個任務的線程,而不用每次新建線程。
          * @author JackRen
          * @date 2021/3/4
          * @return
          **/

          public void cachedThreadPool() {
          for (int i = 0; i < 10; i++) {
          final int index = i;
          try {
          Thread.sleep(index * 1000);
          } catch (InterruptedException e) {
          e.printStackTrace();
          }
          cachedThreadPool.execute(new Runnable() {
          @Override
          public void run() {
          System.out.println(index);
          }
          });
          }
          }


          /*
          * 創(chuàng)建一個定長線程池,可控制線程最大并發(fā)數(shù),超出的線程會在隊列中等待
          * 因為線程池大小為3,每個任務輸出index后sleep 2秒,所以每兩秒打印3個數(shù)字。
          * 定長線程池的大小最好根據(jù)系統(tǒng)資源進行設置
          * @author JackRen
          * @date 2021/3/4
          * @return
          **/

          public void fixedThreadPool () {
          for (int i=0;i<10;i++) {
          final int index = i;
          fixedThreadPool.execute(new Runnable() {
          @Override
          public void run() {
          try{
          System.out.println(index);
          } catch (Exception e) {
          e.printStackTrace();
          }
          }
          });
          }
          }

          /*
          * 創(chuàng)建一個定長線程池,支持定時及周期性任務執(zhí)行
          * 表示延遲3秒執(zhí)行
          * @author JackRen
          * @date 2021/3/4
          * @return
          **/

          public void scheduledThreadPool () {
          scheduledThreadPool.schedule(new Runnable() {
          @Override
          public void run() {
          System.out.println("delay 3 seconds");
          }
          },3, TimeUnit.SECONDS);
          }

          /*
          * 創(chuàng)建一個定長線程池,支持定時及周期性任務執(zhí)行
          * 定期執(zhí)行
          * 表示延遲1秒后每3秒執(zhí)行一次
          * ScheduledExecutorService比Timer更安全,功能更強大
          * @author JackRen
          * @date 2021/3/4
          * @return
          **/

          public void scheduledAtFixedRate () {
          scheduledThreadPool.scheduleAtFixedRate(new Runnable() {
          @Override
          public void run() {
          System.out.println("delay 3 seconds");
          }
          },1,3, TimeUnit.SECONDS);
          }

          /*
          * 創(chuàng)建一個單線程化的線程池,它只會用唯一的工作線程來執(zhí)行任務,保證所有任務按照指定順序(FIFO, LIFO, 優(yōu)先級)執(zhí)行
          * @author JackRen
          * @date 2021/3/4
          * @return
          **/

          public void singleThreadExecutor() {
          for (int i=0;i<10;i++) {
          final int index = i;
          singleThreadExecutor.execute(new Runnable() {
          @Override
          public void run() {
          try{
          System.out.println(index);
          Thread.sleep(2000);
          } catch (Exception e) {
          e.printStackTrace();
          }
          }
          });
          }
          }

          }

          總結(jié):

          線程池的作用:

          線程池作用就是限制系統(tǒng)中執(zhí)行線程的數(shù)量。根據(jù)系統(tǒng)的環(huán)境情況,可以自動或手動設置線程數(shù)量,達到運行的最佳效果;少了浪費了系統(tǒng)資源,多了造成系統(tǒng)擁擠效率不高。用線程池控制線程數(shù)量,其他線程排隊等候。一個任務執(zhí)行完畢,再從隊列的中取最前面的任務開始執(zhí)行。若隊列中沒有等待進程,線程池的這一資源處于等待。當一個新任務需要運行時,如果線程池中有等待的工作線程,就可以開始運行了;否則進入等待隊列。

          為什么要用線程池:

          1.減少了創(chuàng)建和銷毀線程的次數(shù),每個工作線程都可以被重復利用,可執(zhí)行多個任務。

          2.可以根據(jù)系統(tǒng)的承受能力,調(diào)整線程池中工作線線程的數(shù)目,防止因為消耗過多的內(nèi)存,而把服務器累趴下(每個線程需要大約1MB內(nèi)存,線程開的越多,消耗的內(nèi)存也就越大,最后死機)。Java里面線程池的頂級接口是Executor,但是嚴格意義上講Executor并不是一個線程池,而只是一個執(zhí)行線程的工具。真正的線程池接口是ExecutorService。


          瀏覽 53
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          評論
          圖片
          表情
          推薦
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  青娱乐三级片 | 一区在线观看 | 欧美v日韩| 成 人 a v天堂 | 国产三级高清在线 |