1. 程式人生 > 程式設計 >Java程式和執行緒

Java程式和執行緒

概述

程式就是正在執行的程式,它是系統資源排程的獨立單位,並且一個程式可以執行多個任務,而執行緒就是程式執行的任務,它是程式使用CPU的基本單位,因此也可以說執行緒是依賴於程式的。

程式

程式就是正在執行的程式,它是系統資源排程的獨立單位,也是作業系統執行的基本單元,各個程式之間不會相互影響,因為系統給它們分配了不同的空間和資源。他又分為單程式和多程式。

單程式的計算機一次只能做一件事情,而多程式的計算機可以做到一次做不同的事情,比如一邊聽音樂,一邊聽打遊戲,這兩件事情雖然感覺起來是在同時一起進行的,但其實是CPU在做著程式間的高效切換,這才讓我們覺得是同時進行的。

執行緒

執行緒就是程式(程式)執行的任務,它分為單執行緒和多執行緒。

單執行緒也就是做的事情專一,不會分神去做別的事,也就是程式只有一條執行路徑;多執行緒就是可以分出多條路去做同一件事情,也就是程式有多條執行路徑,比如三個夥伴迷路了,大家分別去問路人路線,最後大家在目的地集合,因此多執行緒的存在,不是提高程式的執行速度,其實是為了提高應用程式的使用率,也可以說程式的執行其實都是在搶CPU的資源,也就是搶CPU的執行權,而其中的某一個程式如果執行路徑比較多,就會有更高的機率搶到CPU的執行權,但這一過程是隨機的,不知道哪一個執行緒會在哪一個時刻佔到這個資源,所以執行緒的執行有隨機性。

一個程式至少一個程式,一個程式至少一個執行緒。

優缺點

執行緒執行開銷小,但是不利於資源的管理和保護。執行緒適合在SMP機器(雙CPU系統)上執行。

程式執行開銷大,但是能夠很好的進行資源管理和保護。程式可以跨機器前移。

多執行緒有幾種實現方法?有什麼區別?

實現多執行緒有兩種方式:(自JDK1.5之後有三種,最後一種並不常用)

1.繼承Thread類

2.實現Runnable介面(Callable介面)

一個類如果實現了Runnable介面或者繼承了Thread類,那麼它就是一個多執行緒類,如果是要實現多執行緒,還需要重寫run()方法,所以run() 方法是多執行緒的入口。

多執行緒的兩種實現方式的區別:

1.Thread是Runnable介面的子類,實現Runnable介面的方式解決了Java單繼承的侷限

2.Runnable介面實現多執行緒比繼承Thread類更加能描述資料共享的概念

程式碼演示

購買火車票,共有100張票,而它有3個售票視窗售票,請設計一個程式模擬該火車售票系統,通過實現Runnable介面實現(模擬網路延遲)。

為瞭解決執行緒安全問題,只讓一個執行緒進入,並阻止另一個執行緒進入,那麼就使用到了synchronize(同步程式碼塊)或者繼承Lock(鎖)。

Java記憶體模型規定了所有的變數都儲存在主記憶體中,每條執行緒中還有自己的工作記憶體,工作記憶體中儲存了被該執行緒所使用到的變數(這些變數是從主記憶體中拷貝而來),執行緒對變數的所有操作(讀取,賦值)都必須在工作記憶體中進行,不同執行緒之間也無法直接訪問對方工作記憶體中的變數,它們間變數值的傳遞均需要通過主記憶體來完成。對於解決該問題,Java提供了volatile關鍵字來,該關鍵字保證了記憶體可見性。

synchronize關鍵字程式碼塊

public class Ticket implements Runnable{
    //設定票數
    int ticket = 100;   
    Object obj = new Object();
    
    @Override
    public void run() {
        while (true){
            synchronized (obj) {
                if (ticket > 0) {
                    try {
                        Thread.sleep(1000);//模擬網路延遲
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    
                    System.out.println(Thread.currentThread().getName() + "正在出售" + (ticket--) + "張票"+"====="+Thread.currentThread().getPriority());
                }else {
                    //當票不滿足條件是退出迴圈
                    break;
                }
            
            }

        }
        	
    }
    
    public static void main(String[] args) {
        Ticket ticket = new Ticket();
        
        Thread thread1 = new Thread(ticket);
        thread1.setName("視窗1");
        
        Thread thread2 = new Thread(ticket);
        thread2.setName("視窗2");
        
        Thread thread3 = new Thread(ticket);
        thread3.setName("視窗3");
        
        //開啟執行緒
        thread1.start();
        thread2.start();
        thread3.start();
        
    }
    
}
複製程式碼

繼承Lock(鎖)

public class Ticket implements Runnable{
    //設定票數
    int ticket = 100;
    Lock lock = new ReentrantLock();
    
    @Override
    public void run() {
        while (true){
                lock.lock();
                if (ticket > 0) {
                    try {
                        Thread.sleep(50);//模擬網路延遲
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    
                    System.out.println(Thread.currentThread().getName() + "正在出售" + (ticket--) + "張票"+"====="+Thread.currentThread().getPriority());
                    lock.unlock();
                }else {
                    
                    //當票不滿足條件是退出迴圈
                    break;
                }

        }
        	
    }

    public static void main(String[] args) {
        Ticket2 ticket = new Ticket2();
        
        Thread thread1 = new Thread(ticket);
        thread1.setName("視窗1");
        thread1.setPriority(4);
        
        Thread thread2 = new Thread(ticket);
        thread2.setName("視窗2");
        thread2.setPriority(5);
        
        Thread thread3 = new Thread(ticket);
        thread3.setName("視窗3");
        thread2.setPriority(7);
        
        //開啟執行緒
        thread1.start();
        thread2.start();
        thread3.start();
        
    }
    
}

複製程式碼

執行結果

視窗1正在出售100張票=====5
視窗1正在出售99張票=====5
視窗1正在出售98張票=====5
視窗1正在出售97張票=====5
視窗1正在出售96張票=====5
視窗1正在出售95張票=====5
視窗1正在出售94張票=====5
視窗3正在出售93張票=====5
視窗2正在出售92張票=====5
視窗2正在出售91張票=====5
視窗3正在出售90張票=====5
視窗1正在出售89張票=====5
視窗1正在出售88張票=====5
視窗3正在出售87張票=====5
視窗3正在出售86張票=====5
視窗3正在出售85張票=====5
視窗3正在出售84張票=====5
視窗2正在出售83張票=====5
視窗3正在出售82張票=====5
視窗1正在出售81張票=====5
視窗1正在出售80張票=====5
視窗1正在出售79張票=====5
視窗1正在出售78張票=====5
視窗1正在出售77張票=====5
視窗3正在出售76張票=====5
視窗2正在出售75張票=====5
視窗3正在出售74張票=====5
視窗1正在出售73張票=====5
視窗3正在出售72張票=====5
視窗2正在出售71張票=====5
視窗3正在出售70張票=====5
視窗1正在出售69張票=====5
視窗3正在出售68張票=====5
視窗2正在出售67張票=====5
視窗2正在出售66張票=====5
視窗3正在出售65張票=====5
視窗1正在出售64張票=====5
視窗3正在出售63張票=====5
視窗2正在出售62張票=====5
視窗2正在出售61張票=====5
視窗2正在出售60張票=====5
視窗3正在出售59張票=====5
視窗3正在出售58張票=====5
視窗1正在出售57張票=====5
視窗1正在出售56張票=====5
視窗1正在出售55張票=====5
視窗1正在出售54張票=====5
視窗1正在出售53張票=====5
視窗3正在出售52張票=====5
視窗3正在出售51張票=====5
視窗3正在出售50張票=====5
視窗3正在出售49張票=====5
視窗3正在出售48張票=====5
視窗3正在出售47張票=====5
視窗3正在出售46張票=====5
視窗2正在出售45張票=====5
視窗3正在出售44張票=====5
視窗1正在出售43張票=====5
視窗1正在出售42張票=====5
視窗1正在出售41張票=====5
視窗1正在出售40張票=====5
視窗1正在出售39張票=====5
視窗1正在出售38張票=====5
視窗1正在出售37張票=====5
視窗1正在出售36張票=====5
視窗1正在出售35張票=====5
視窗1正在出售34張票=====5
視窗1正在出售33張票=====5
視窗1正在出售32張票=====5
視窗1正在出售31張票=====5
視窗1正在出售30張票=====5
視窗1正在出售29張票=====5
視窗1正在出售28張票=====5
視窗1正在出售27張票=====5
視窗1正在出售26張票=====5
視窗1正在出售25張票=====5
視窗1正在出售24張票=====5
視窗1正在出售23張票=====5
視窗3正在出售22張票=====5
視窗3正在出售21張票=====5
視窗3正在出售20張票=====5
視窗2正在出售19張票=====5
視窗2正在出售18張票=====5
視窗3正在出售17張票=====5
視窗3正在出售16張票=====5
視窗3正在出售15張票=====5
視窗1正在出售14張票=====5
視窗1正在出售13張票=====5
視窗1正在出售12張票=====5
視窗1正在出售11張票=====5
視窗1正在出售10張票=====5
視窗1正在出售9張票=====5
視窗1正在出售8張票=====5
視窗1正在出售7張票=====5
視窗3正在出售6張票=====5
視窗3正在出售5張票=====5
視窗3正在出售4張票=====5
視窗3正在出售3張票=====5
視窗3正在出售2張票=====5
視窗3正在出售1張票=====5

複製程式碼