JAVA如何實(shí)現(xiàn)多線程筆記

一、什么是線程

線程是獨(dú)立調(diào)度和分派的基本單位,它被包含在進(jìn)程之中,是進(jìn)程中的實(shí)際運(yùn)作單位

二、什么是進(jìn)程

進(jìn)程是一個(gè)具有一定獨(dú)立功能的程序關(guān)于某個(gè)數(shù)據(jù)集合的一次運(yùn)行活動(dòng)。它是操作系統(tǒng)動(dòng)態(tài)執(zhí)行的基本單元,在傳統(tǒng)的操作系統(tǒng)中,進(jìn)程既是基本的分配單元,也是基本的執(zhí)行單元。
一個(gè)進(jìn)程可以包含有多個(gè)線程

三、java多線程的實(shí)現(xiàn)方式

1、實(shí)現(xiàn)方法簡(jiǎn)述

方法一 方法二
繼承Thread類,重寫run()方法,執(zhí)行start()方法啟動(dòng)多線程 普通類實(shí)現(xiàn)Runnable接口,重寫run()方法,啟動(dòng)時(shí),使用Thread類裝載線程對(duì)象,最后使用start方法啟動(dòng)(方法二比較常用,因?yàn)閖ava類是單繼承的,盡量使用接口)

2、實(shí)例

方法一:繼承Thread類,重寫run()方法,執(zhí)行start()方法啟動(dòng)多線程

/**
 * @description 線程測(cè)試類,使用第一種實(shí)現(xiàn)方式
 * 第一步 繼承Thread類
 * 第二步重寫run()方法
 * 第三步執(zhí)行start()方法啟動(dòng)多線程
 * @version 1.0
 * @author manyu
 * @address www.mpmanyu.com
 * @update 2021年3月26日 下午10:51:59
 *
 */
public class TestThread2 extends Thread {
    
    @Override
    public void run() {
        for (int i = 0; i < 1000; i++) {
        System.out.println("i="+i);
        };
    }

}

TestThread1類自己建立一個(gè),內(nèi)容相同
創(chuàng)建進(jìn)程啟動(dòng)類

/**
 * @description 測(cè)試線程,同時(shí)運(yùn)行TestThread1 ,TestThread2 兩個(gè)類的對(duì)象
 * @version 1.0
 * @author manyu
 * @address www.mpmanyu.com
 * @update 2021年3月26日 下午11:05:11
 * 
 */
public class ThreadWindows {
    public static void main(String[] args) {
        //第一個(gè)線程對(duì)象
        TestThread1 test1 = new TestThread1();
        //第二個(gè)線程對(duì)象
        TestThread2 test2 = new TestThread2();
        //同時(shí)啟動(dòng)test1 與 test2
        test1.start();
        test2.start();
    }

}

執(zhí)行結(jié)果如下

i=9
i=10
j=0
i=11
j=1
i=12
i=13
i=14
.......

方法二:普通類實(shí)現(xiàn)Runnable接口,使用Thread類裝載線程對(duì)象,最后使用start方法啟動(dòng)(方法二比較常用,因?yàn)閖ava類是單繼承的,盡量使用接口)

代碼如下:
建立ThreadDemo3 ThreadDemo4兩個(gè)類,內(nèi)容相同

 /** 
 * @ClassName: ThreadDemo3 
 * @Description: 使用第二種方式啟動(dòng)線程
 * 實(shí)現(xiàn)Runnable接口,裝載線程,啟動(dòng)線程
 * @author: manyu
 * @date: 2021年3月27日 上午10:43:10  
 */
public class ThreadDemo3 implements Runnable{

    /* (non-Javadoc)
     * @see java.lang.Runnable#run()
     * 使用第二種方式啟動(dòng)線程
     */
    @Override
    public void run() {
        for(int i =0;i<1000;i++) {
            System.out.println("第二種方式啟動(dòng) i="+i);
            Thread.yield();
        }
        
    }

}

建立啟動(dòng)類

 /** 
 * @ClassName: ThreadWindow 
 * @Description: 使用第二種方式啟動(dòng)多線程
 * @author: manyu
 * @date: 2021年3月27日 上午8:06:56  
 */
public class ThreadWindow2 {

    /** 
    * @Title: main 
    * @Description: 使用第二種方式啟動(dòng)線程 
    * @param args 
    * @author manyu
    * @update 2021年3月27日上午8:06:56
    */
    public static void main(String[] args) {
        //創(chuàng)建thread3對(duì)象 
        ThreadDemo3 threadDemo3 = new ThreadDemo3();
        Thread thread3 = new Thread(threadDemo3);
        thread3.start();
        //創(chuàng)建thread4對(duì)象
        ThreadDemo4 threadDemo4 = new ThreadDemo4();
        Thread thread4 = new Thread(threadDemo4);
        thread4.start();
        
        
    
    }

}

四、java線程安全問題

1、線程安全問題出現(xiàn)的前提

當(dāng)多個(gè)線程操作同一共享數(shù)據(jù)的時(shí)候,就會(huì)產(chǎn)生線程安全問題。

2、如何解決線程安全問題

給共享數(shù)據(jù)加鎖,使用synchronized (類.class)

例如:賣票小案例
售票系統(tǒng)類說明:TicketDemo類是賣票的線程類,共200張票,不同的站點(diǎn)進(jìn)行賣票,假設(shè)完成一次售票需要10ms時(shí)間。

 /** 
 * @ClassName: TicketDemo 
 * @Description: 購票軟件實(shí)例 共有200張票,n個(gè)售票窗口進(jìn)行售票
 * @author: manyu
 * @address: www.mpmanyu.com
 * @date: 2021年3月27日 下午4:04:02  
 */
public class TicketDemo implements Runnable {
    private static int TICKETNUM = 200; //一共有200張票

    @Override
    public void run() {
        try {
            for(int i = 2000; i>0;i--) {
                //必須給售票的整個(gè)過程加鎖,保證一個(gè)線程處理完成后才能后下一個(gè)線程進(jìn)行賣票
                synchronized (TicketDemo.class) {
                    if(TICKETNUM>0) {
                        TICKETNUM--;
                        System.out.println("剩余票數(shù)="+TICKETNUM);
                        Thread.sleep(10);//假設(shè)一次售票需要10ms
                    }
                }

            }
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
}

窗口類說明:WindowThread類是窗口類,模擬多個(gè)窗口同時(shí)售票。如果要所有的售票點(diǎn)能夠正常售票,不要超賣。造成 售票量>總票量(200),必須在給整個(gè)的售賣過程加鎖。

 /** 
 * @ClassName: WindowThread 
 * @Description: 售票測(cè)試的窗口測(cè)試程序
 * @author: manyu
 * @address: www.mpmanyu.com
 * @date: 2021年3月27日 下午4:09:46  
 */
public class WindowThread {
    public static void main(String[] args) {
        //窗口1
        TicketDemo win1 = new TicketDemo();
        Thread win1Thread = new Thread(win1);
        //窗口2
        TicketDemo win2 = new TicketDemo();
        Thread win2Thread = new Thread(win2);
        //窗口3
        TicketDemo win4 = new TicketDemo();
        Thread win4Thread = new Thread(win4);
        //窗口4
        TicketDemo win5 = new TicketDemo();
        Thread win5Thread = new Thread(win5);
        
        //開始售票
        win1Thread.start();
        win2Thread.start();
        win4Thread.start();
        win5Thread.start();
    }
}

3、run()與start()方法的區(qū)別

run()方法相當(dāng)于調(diào)用普通方法,它是順序執(zhí)行,實(shí)際還是單線程;
start()方法真正啟動(dòng)線程,

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容