欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Java線程創(chuàng)建的四種方式總結(jié)

 更新時(shí)間:2021年09月14日 09:31:01   作者:威斯布魯克.猩猩  
這篇文章主要介紹了Java線程創(chuàng)建的四種方式,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下

多線程的創(chuàng)建,方式一:繼承于Thread類

1.創(chuàng)建一個(gè)繼承于Thread類的子類

2.重寫Thread類的run()--->將此線程執(zhí)行的操作聲明在run()中

3.創(chuàng)建Thread類的子類的對(duì)象

4.通過(guò)此對(duì)象調(diào)用start():

start()方法的兩個(gè)作用:

A.啟動(dòng)當(dāng)前線程

B.調(diào)用當(dāng)前線程的run()

創(chuàng)建過(guò)程中的兩個(gè)問(wèn)題:

問(wèn)題一:我們不能通過(guò)直接調(diào)用run()的方式啟動(dòng)線程

問(wèn)題二:在啟動(dòng)一個(gè)線程,遍歷偶數(shù),不可以讓已經(jīng)start()的線程去執(zhí)行,會(huì)報(bào)異常;正確的方式是重新創(chuàng)建一個(gè)線程的對(duì)象。

//1.創(chuàng)建一個(gè)繼承于Thread類的子類
class MyThread extends Thread{
    //2.重寫Thread類的run()
    @Override
    public void run() {//第二個(gè)線程
       for(int i = 0;i < 10;i++){
           if(i % 2 == 0){
               System.out.println(i);
           }
       }
    }
}
public class ThreadTest {
    public static void main(String[] args) {//主線程
        //3.創(chuàng)建Thread類的子類的對(duì)象
        MyThread t1 = new MyThread();
        //4.通過(guò)此對(duì)象調(diào)用start()
        t1.start();
        //問(wèn)題一:不能通過(guò)直接調(diào)用run()的方式啟動(dòng)線程
//        t1.run();//錯(cuò)誤的
        //問(wèn)題二:再啟動(dòng)一個(gè)線程:我們需要再創(chuàng)建 一個(gè)對(duì)象
        //t1.start();//錯(cuò)誤的
        MyThread t2 = new MyThread();
        t2.start();
 
        for(int i = 0;i < 10;i++){
            if(i % 2 != 0){
                System.out.println(i + "****main()******");
            }
        }
    }
}

此代碼在主線程內(nèi)輸出奇數(shù),在另一個(gè)線程里輸出偶數(shù),則輸出結(jié)果應(yīng)該是兩個(gè)輸出結(jié)果是交互的。

1****main()******
3****main()******
5****main()******
7****main()******
0
2
4
6
8
9****main()******

class Window extends Thread{//創(chuàng)建三個(gè)窗口賣票, 總票數(shù)為100張,使用繼承于Thread類的方式
    private static int ticket = 100;//三個(gè)窗口共享:聲明為static
    @Override
    public void run() {
        while(true){
            if(ticket > 0){
                System.out.println(getName() + ":賣票,票號(hào)為:" + ticket);
                ticket--;
            }else{
                break;
            }
        }
    }
}
public class WindowTest2 {
    public static void main(String[] args) {
        Window t1 = new Window();
        Window t2 = new Window();
        Window t3 = new Window();
        t1.setName("窗口1");
        t2.setName("窗口2");
        t3.setName("窗口3");
        t1.start();
        t2.start();
        t3.start();
    }
}
public class ThreadDemo {
    public static void main(String[] args) {
//        MyThread1 m1 = new MyThread1();
//        MyThread2 m2 = new MyThread2();
//        m1.start();
//        m2.start();
        //由于造的類只創(chuàng)建過(guò)一次對(duì)象,后面就不用了,可以考慮使用匿名類的方式
        //創(chuàng)建Thread類的匿名子類的方式
        new Thread(){
            @Override
            public void run() {
                for(int i = 0;i < 100;i++){
                    if(i % 2 == 0){
                        System.out.println(i);
                    }
                }
            }
        }.start();
        new Thread(){
            @Override
            public void run() {
                for(int i = 0;i < 100;i++){
                    if(i % 2 != 0){
                        System.out.println(i);
                    }
                }
            }
        }.start();
    }
}
class MyThread1 extends Thread{
    @Override
    public void run() {
        for(int i = 0;i < 100;i++){
            if(i % 2 == 0){
                System.out.println(i);
            }
        }
    }
}
class MyThread2 extends Thread{
    @Override
    public void run() {
        for(int i = 0;i < 100;i++){
            if(i % 2 != 0){
                System.out.println(i);
            }
        }
    }
}

創(chuàng)建多線程的方式二:實(shí)現(xiàn)Runnable接口

  • 創(chuàng)建一個(gè)實(shí)現(xiàn)了Runnable接口的類
  • 實(shí)現(xiàn)類去實(shí)現(xiàn)Runnable中的抽象方法:run()
  • 創(chuàng)建實(shí)現(xiàn)類的對(duì)象
  • 將此對(duì)象作為參數(shù)傳遞到Thread類的構(gòu)造器中,創(chuàng)建Thread類的對(duì)象
  • 通過(guò)Thread類的對(duì)象調(diào)用start()
class MThread implements Runnable{
    //2.實(shí)現(xiàn)類去實(shí)現(xiàn)Runnable中的抽象方法:run()
    @Override
    public void run() {
        for(int i = 0;i < 100;i++){
            if (i % 2 == 0) {
                System.out.println(Thread.currentThread().getName() + ":" + i);
            }
        }
    }
}
public class ThreadTest1 {
    public static void main(String[] args) {
        //3.創(chuàng)建實(shí)現(xiàn)類的對(duì)象
        MThread mThread = new MThread();
        //4.將此對(duì)象作為參數(shù)傳遞到Thread類的構(gòu)造器中,創(chuàng)建Thread類的對(duì)象
        Thread t1 = new Thread(mThread);
        t1.setName("線程1");
        //5.通過(guò)Thread類的對(duì)象調(diào)用start():A.啟動(dòng)線程B.調(diào)用當(dāng)前線程的run()-->調(diào)用了Runnable類型的target
        t1.start();
        //再啟動(dòng)一個(gè)線程,遍歷100以內(nèi)的偶數(shù)//只需重新實(shí)現(xiàn)步驟4,5即可
        Thread t2 = new Thread(mThread);
        t2.setName("線程2");
        t2.start();
    }
}
class window1 implements Runnable{//創(chuàng)建三個(gè)窗口賣票, 總票數(shù)為100張,使用實(shí)現(xiàn)Runnable接口的方式
    private int ticket = 100;
    Object obj = new Object();
    @Override
    public void run() {
        while (true){
            if (ticket > 0) {
                System.out.println(Thread.currentThread().getName() + "賣票,票號(hào)為:" + ticket);
                ticket--;
            } else {
                break;
            }
        }
    }
}
public class WindowTest {
    public static void main(String[] args) {
        window1 w = new window1();//只造了一個(gè)對(duì)象,所以100張票共享
        Thread t1 = new Thread(w);
        Thread t2 = new Thread(w);
        Thread t3 = new Thread(w);
        t1.setName("線程1");
        t2.setName("線程2");
        t3.setName("線程3");
        t1.start();
        t2.start();
        t3.start();
    }
}

創(chuàng)建線程的方式三:實(shí)現(xiàn)Callable接口---JDK5.0新增

與使用Runnable相比,Callable功能更強(qiáng)大些

>相比run()方法,可以有返回值

>方法可以拋出異常

>支持泛型的返回值

>需要借助FutureTask類,比如獲取返回結(jié)果

Future接口

>可以對(duì)具體Runnable、Callable任務(wù)的執(zhí)行結(jié)果進(jìn)行取消、查詢是否完成、獲取結(jié)果等。

>FutureTask是Futrue接口的唯一的實(shí)現(xiàn)類

>FutureTaskb同時(shí)實(shí)現(xiàn)了Runnable,Future接口。它既可以作為Runnable被線程執(zhí)行,又可以作為Future得到Callable的返回值

//1.創(chuàng)建一個(gè)實(shí)現(xiàn)Callable的實(shí)現(xiàn)類
class NumThread implements Callable{
    //2.實(shí)現(xiàn)call方法,將此線程需要執(zhí)行的操作聲明在call()中
    @Override
    public Object call() throws Exception {
        int sum = 0;
        for(int i = 1;i <= 100;i++){
            if(i % 2 == 0){
                System.out.println(i);
                sum += i;
            }
        }
        return sum;//sum是int,自動(dòng)裝箱為Integer(Object的子類)
    }
}
public class ThreadNew {
    public static void main(String[] args) {
        //3.創(chuàng)建Callable接口實(shí)現(xiàn)類的對(duì)象
        NumThread numThread = new NumThread();
        //4.將此Callable接口實(shí)現(xiàn)類的對(duì)象作為參數(shù)傳遞到 FutureTask的構(gòu)造器中,創(chuàng)建FutureTask的對(duì)象
        FutureTask futureTask = new FutureTask(numThread);
        //5.將 FutureTask的對(duì)象作為參數(shù)傳遞到Thread類的構(gòu)造器中,創(chuàng)建Thread對(duì)象,并調(diào)用start()
        new Thread(futureTask).start();
        try {
            //獲取Callable中call()的返回值(不是必須的步驟)
            //get()返回值即為FutureTask構(gòu)造器參數(shù)Callable實(shí)現(xiàn)類重寫的call()的返回值。
            Object sum = futureTask.get();
            System.out.println("總和為:" + sum);
        } catch (InterruptedException e) {
            e.printStackTrace();
        } catch (ExecutionException e) {
            e.printStackTrace();
        }
    }
}

創(chuàng)建線程的方式四:使用線程池--->JDK5.0新增

背景:經(jīng)常創(chuàng)建和銷毀、使用量特別大的資源,比如并發(fā)情況下的線程,對(duì)性能影響很大。

思路:提前創(chuàng)建好多個(gè)線程,放入線程池中,使用時(shí)直接獲取,使用完放回池中。可以避免頻繁創(chuàng)建銷毀、實(shí)現(xiàn)重復(fù)利用。類似生活中的公共交通工具。

好處:>提高響應(yīng)速度(減少了創(chuàng)建新線程的時(shí)間)

>降低資源消耗(重復(fù)利用線程池中線程,不需要每次都創(chuàng)建)

>便于線程管理:A.corePoolSize:核心池的大小 B.maximumPoolSize:最大線程數(shù) C.keepAliveTime:線程沒(méi)有任務(wù)時(shí)最多保持多長(zhǎng)時(shí)間后會(huì)終止

class NumberThread implements Runnable{
 
    @Override
    public void run() {
        for(int i = 0;i <= 100;i++){
            if(i % 2 == 0){
                System.out.println(Thread.currentThread().getName() + ":" + i);
            }
        }
    }
}
class NumberThread1 implements Runnable{
    @Override
    public void run() {
        for(int i = 0;i <= 100;i++){
            if(i % 2 != 0){
                System.out.println(Thread.currentThread().getName() + ":" + i);
            }
        }
    }
}
public class ThreadPool {
    public static void main(String[] args) {
        //1.提供指定線程數(shù)量的線程池
        ExecutorService service = Executors.newFixedThreadPool(10);
        ThreadPoolExecutor service1 = (ThreadPoolExecutor) service;
        //設(shè)置線程池的屬性
//        System.out.println(service.getClass());
//        service1.setCorePoolSize(15);
//        service1.setKeepAliveTime();
        //2.執(zhí)行指定的線程操作。需要提供實(shí)現(xiàn)Runnable 接口或Callable接口實(shí)現(xiàn)類的對(duì)象
        service.execute(new NumberThread());//適用于Runnable
        service.execute(new NumberThread1());//適用于Runnable
//        service.submit(Callable callable);//適用于Callable
        //3.關(guān)閉連接池
        service.shutdown();
    }
}

比較創(chuàng)建線程的兩種方式:

開發(fā)中:優(yōu)先選擇:實(shí)現(xiàn)Runnable接口的方式
原因:1.實(shí)現(xiàn)的方式?jīng)]有類的單繼承性的局限性
2.實(shí)現(xiàn)的方式更適合來(lái)處理多個(gè)線程有共享數(shù)據(jù)的情況。
系:public class Thread implements Runnable
相同點(diǎn):兩種方式都需要重寫run(),將線程要執(zhí)行的邏輯聲明在run()中

程序(program)是為完成特定任務(wù)、用某種語(yǔ)言編寫的一組指令的集合。即指一段靜態(tài)的代碼,靜態(tài)對(duì)象。

進(jìn)程(process)是程序的一次執(zhí)行過(guò)程,或是正在運(yùn)行的一個(gè)程序。是一個(gè)動(dòng)態(tài)的過(guò)程:有它自身的產(chǎn)生、存在和消亡的過(guò)程。---生命周期

線程(thread),進(jìn)程可進(jìn)一步細(xì)化為線程,是一個(gè)程序內(nèi)部的一條執(zhí)行路徑。

線程作為調(diào)度和執(zhí)行的單位,每個(gè)線程擁有獨(dú)立的運(yùn)行棧和計(jì)數(shù)器,每個(gè)進(jìn)程擁有獨(dú)立的方法區(qū)和堆;意味著,多個(gè)線程共享一個(gè)方法區(qū)和堆。而共享的就可以優(yōu)化,同時(shí),共享的也會(huì)帶來(lái)安全隱患,這就需要我們解決線程安全問(wèn)題

背景:以單核CPU為例,只使用單個(gè)線程先后完成多個(gè)任務(wù)(調(diào)用多個(gè)方法),肯定比用多個(gè)線程來(lái)完成用的時(shí)間更短,為何仍需使用多線程呢?

使用多線程的優(yōu)點(diǎn):

1.提高應(yīng)用程序的響應(yīng)。對(duì)圖形化界面更有意義,可增強(qiáng)用戶體驗(yàn)。

2.提高計(jì)算機(jī)系統(tǒng)CPU的利用率

3.改善程序結(jié)構(gòu)。將即長(zhǎng)又復(fù)雜的線程分為多個(gè)線程,獨(dú)立運(yùn)行,利于理解和修改

何時(shí)需要多線程

1.程序需要同時(shí)執(zhí)行兩個(gè)或多個(gè)任務(wù)。

2.程序需要實(shí)現(xiàn)一些需要等待的任務(wù)時(shí),如用戶輸入、文件讀寫操作、網(wǎng)絡(luò)操作、搜索等。

3.需要一些后臺(tái)運(yùn)行的程序時(shí)。

public class Sample{
    public void method1(String str){
        System.out.println(str);
    }
    public void method2(String str){
        method1(str);
    }
    public static void main(String[] args){
        Sample s = new Sample();
        s.method2("hello!");
    }
}

注意:此程序不是多線程!main方法中調(diào)用了method1,method1中又調(diào)用了method2;是一條執(zhí)行路徑,所以是單線程

測(cè)試Thread類的常用方法:

1.start():啟動(dòng)當(dāng)前線程:調(diào)用當(dāng)前線程的run()
2.run():通常需要重寫Thread類中的此方法,將創(chuàng)建的線程要執(zhí)行的操作聲明在此方法中
3.currentThread():靜態(tài)方法,返回執(zhí)行當(dāng)前代碼的線程
4.getName():獲取當(dāng)前線程的名字
5.setName():設(shè)置當(dāng)前線程的名字
6.yield():釋放當(dāng)前CPU的執(zhí)行權(quán)(下一刻CPU執(zhí)行的線程仍是隨機(jī)的)
>暫停當(dāng)前正在執(zhí)行的線程,把執(zhí)行機(jī)會(huì)讓給優(yōu)先級(jí)相同或更高的線程
>若隊(duì)列中沒(méi)有同優(yōu)先級(jí)的線程,忽略此方法
7.join():在線程a中調(diào)用線程b的join(),此時(shí),線程a就進(jìn)入阻塞狀態(tài)(停止執(zhí)行),直到線程b完全執(zhí)行完以后,線程b才結(jié)束阻塞狀態(tài)(開始執(zhí)行)。
8.sleep(long millitime):讓當(dāng)前線程"睡眠"指定的millitime毫秒。在指定的millitime毫秒時(shí)間內(nèi),當(dāng)前線程是阻塞狀態(tài)。會(huì)拋出InterruptedException異常
* 9.isAlive():判斷當(dāng)前線程是否存活

class HelloThread extends Thread{
    @Override
    public void run() {
        for(int i = 0;i < 100;i++){
            if(i % 2 != 0){
                try {
                    sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println(Thread.currentThread().getName() + ":" +Thread.currentThread().getPriority() + ":" + i);
            }
        }
    }
    public HelloThread(String name){
        super(name);
    }
}
public class ThreadMethodTest {
    public static void main(String[] args) {
        HelloThread h1 = new HelloThread("Thread:1");//通過(guò)構(gòu)造器給線程命名,但前期是得在子類中提供一個(gè)構(gòu)造器
//        h1.setName("線程一");
        //設(shè)置分線程的優(yōu)先級(jí)
        h1.setPriority(Thread.MAX_PRIORITY);
        h1.start();
        //給主線程命名
        Thread.currentThread().setName("主線程");
        Thread.currentThread().setPriority(Thread.MIN_PRIORITY);
        for(int i = 0;i < 100;i++){
            if(i % 2 == 0) {
                System.out.println(Thread.currentThread().getName() + ":" + Thread.currentThread().getPriority() + ":" + i);
            }
//            if(i == 20){
//                try {
//                    h1.join();//join()的測(cè)試
//                } catch (InterruptedException e) {
//                    e.printStackTrace();
//                }
//            }
        }
    }
}

線程的優(yōu)先級(jí):

1.MAX_PRIORITY:10
MIN_PRIORITY:1
NORM_PRIORITY:5--->默認(rèn)優(yōu)先級(jí)
2.如何獲取和設(shè)置當(dāng)前線程的優(yōu)先級(jí):
getPriority():獲取線程的優(yōu)先級(jí)
setPriority(int p):設(shè)置線程的優(yōu)先級(jí)
說(shuō)明:高優(yōu)先級(jí)的線程要搶占低優(yōu)先級(jí)線程CPU的執(zhí)行權(quán),但是只是從概率上講,高優(yōu)先級(jí)的線程高概率的情況下,不一定被執(zhí)行,并不意味著只有當(dāng)高優(yōu)先級(jí)的線程執(zhí)行完畢后,低優(yōu)先級(jí)的線程才執(zhí)行。

到此這篇關(guān)于Java線程創(chuàng)建的四種方式總結(jié)的文章就介紹到這了,更多相關(guān)Java 線程創(chuàng)建內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Java?Collections工具類中常用算法解析

    Java?Collections工具類中常用算法解析

    在軟件開發(fā)中,算法是非常重要的一部分,它們可以提供高效的數(shù)據(jù)處理和操作,這篇文章主要為大家介紹了Collections?工具類集合框架中常用算法,感興趣的可以了解一下
    2023-06-06
  • Java的項(xiàng)目構(gòu)建工具M(jìn)aven的配置和使用教程

    Java的項(xiàng)目構(gòu)建工具M(jìn)aven的配置和使用教程

    Maven是Java世界中的項(xiàng)目管理和構(gòu)建自動(dòng)化工具,基于POM項(xiàng)目對(duì)象模型的思想,下面我們就具體來(lái)看一下具體的Java的項(xiàng)目構(gòu)建工具M(jìn)aven的配置和使用教程:
    2016-05-05
  • Java中static作用詳解

    Java中static作用詳解

    這篇文章主要介紹了Java中static作用,static表示“全局”或者“靜態(tài)”的意思,用來(lái)修飾成員變量和成員方法,也可以形成靜態(tài)static代碼塊,需要的朋友可以參考下
    2015-09-09
  • JAVA設(shè)計(jì)模式---單例模式你知道嗎

    JAVA設(shè)計(jì)模式---單例模式你知道嗎

    這篇文章主要給大家介紹了關(guān)于Java單例模式,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家學(xué)習(xí)或者使用Java具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2021-09-09
  • Java 實(shí)戰(zhàn)項(xiàng)目錘煉之網(wǎng)上花店商城的實(shí)現(xiàn)流程

    Java 實(shí)戰(zhàn)項(xiàng)目錘煉之網(wǎng)上花店商城的實(shí)現(xiàn)流程

    讀萬(wàn)卷書不如行萬(wàn)里路,只學(xué)書上的理論是遠(yuǎn)遠(yuǎn)不夠的,只有在實(shí)戰(zhàn)中才能獲得能力的提升,本篇文章手把手帶你用java+jsp+servlet+mysql+ajax實(shí)現(xiàn)一個(gè)網(wǎng)上花店商城系統(tǒng),大家可以在過(guò)程中查缺補(bǔ)漏,提升水平
    2021-11-11
  • 關(guān)于Spring?@Transactional事務(wù)傳播機(jī)制詳解

    關(guān)于Spring?@Transactional事務(wù)傳播機(jī)制詳解

    我們?nèi)粘9ぷ髦袠O少使用事務(wù)傳播級(jí)別,單純只是使用事務(wù)和rollbackfor拋出異常來(lái)解決事務(wù)問(wèn)題,但其實(shí)我們很多時(shí)候使用的是不正確的,或者說(shuō)會(huì)造成事務(wù)粒度過(guò)大,本文詳解一下事務(wù)傳播級(jí)別,也讓自己更好地處理事務(wù)問(wèn)題,需要的朋友可以參考下
    2023-08-08
  • Java性能工具JMeter實(shí)現(xiàn)上傳與下載腳本編寫

    Java性能工具JMeter實(shí)現(xiàn)上傳與下載腳本編寫

    性能測(cè)試工作中,文件上傳也是經(jīng)常見(jiàn)的性能壓測(cè)場(chǎng)景之一,那么 JMeter 文件上傳下載腳本怎么做,本文詳細(xì)的來(lái)介紹一下,感興趣的可以了解一下
    2021-07-07
  • 如何將Java對(duì)象轉(zhuǎn)換成JSON

    如何將Java對(duì)象轉(zhuǎn)換成JSON

    這篇文章主要介紹了如何將Java對(duì)象轉(zhuǎn)換成JSON,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友參考下吧
    2023-11-11
  • 淺談Java中ArrayList的擴(kuò)容機(jī)制

    淺談Java中ArrayList的擴(kuò)容機(jī)制

    本文主要介紹了淺談Java中ArrayList的擴(kuò)容機(jī)制,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2023-06-06
  • Spring Security @PreAuthorize注解分析

    Spring Security @PreAuthorize注解分析

    本教程介紹了如何使用 Spring 方法級(jí)安全和 @PreAuthorize 注解來(lái)保護(hù) RestController 方法,通過(guò)這些步驟,您可以確保只有具有適當(dāng)角色或權(quán)限的用戶才能訪問(wèn)特定的 REST API,感興趣的朋友跟隨小編一起看看吧
    2024-11-11

最新評(píng)論