多線程

并行:指兩個和多個時間在同一時刻發(fā)生。
并發(fā):指兩個或多個時間在同一時間段內發(fā)生。

在操作系統(tǒng)中,在很多道程序環(huán)境下,并發(fā)性指在同一時間段內有多個程序在同時運行,但在單CPU操作系統(tǒng)下,每一時刻只能有一道程序執(zhí)行(時間片:CPU分配給各個程序的時間),故這些程序只能是分時的交替進行(但是速度很快,把1秒鐘分成1萬個時間片)而不是我們以為的同時在運行多個程序。
倘若計算機系統(tǒng)有多個CPU,則這些可以并發(fā)執(zhí)行的程序被分配到多個處理器上,實現(xiàn)多任務并行操作,因為是微觀的,所以大家在使用電腦時感覺是多個程序同時執(zhí)行的。
從宏觀角度理解線程是并行運行的,微觀角度看的話是串行運行的,
當系統(tǒng)只有一個CPU時,線程會以某種順序執(zhí)行多個線程,我們把這種情況稱之為線程的調度。

線程和進程的區(qū)別:

進程:有獨立的內存空間,進程中的數(shù)據(jù)存放空間(堆空間和??臻g),是獨立的,至少有一個線程
線程:棧空間是獨立的,堆空間是共享的,線程消耗的資源比進程小。
線程先后執(zhí)行的順序是由CPU(JVM)調度的,進程的執(zhí)行是由CPU控制的。
在一個java程序中,至少包含兩個線程,main線程,垃圾回收線程(后臺線程,用來不定時的回收垃圾,不能說等主方法運行完了再回收,是隨機不定時動態(tài)回收的)

創(chuàng)建線程

a.繼承Thread類
b.實現(xiàn)Runnable接口(當用這種方法時,只是實現(xiàn)了這個接口,它并不是線程類,沒有start方法,所以要創(chuàng)建線程的對象)
線程類:Thread和其子類才叫做線程類
啟動線程時不要調用run方法,而是調用start方法。如果調用run方法只是單純的用對象調用了一次方法,而并沒有啟動線程,程序還只是一個線程。

繼承方式和實現(xiàn)方式的區(qū)別:

繼承方式:從多線程共享資源上分析,繼承方式不能做到3個同學吃150個蘋果
實現(xiàn)方式:共享同一個資源,3個同學吃了50個蘋果

線程不安全

解決
1.同步代碼塊
synchronized(this:當前對象的鎖){需要通同步的代碼塊}
2.同步方法
3.鎖機制
Lock是接口,創(chuàng)建其實現(xiàn)類的對象: final Lock lock=new ReentranLock()
兩個方法:
lock.lock
lock.unlock

synchronized的好與壞

安全但是性能低
建議:較少它所包含的代碼塊

面試題

StringBuffer與StringBuilder區(qū)別:
StringBuffer用synchronized修飾,安全,性能不高
StringBuilder不用synchronized修飾,不安全,性能高
ArrayList和vector(前身,安全,性能差)
Hashmap和Hashtable(前身,安全,性能差)

wait()和notify()

等待與喚醒:可以讓多個線程有序的逐條工作
wait使其下面的代碼阻塞并且釋放鎖
wait和notify必須在同步synchronized中使用


經(jīng)典的消費者案例

//共享資源案例
public class shareSource {
    private String name;
    private String sex;
    boolean isNull=true;
    //添加數(shù)據(jù)
    public synchronized void add(String name,String sex) throws InterruptedException {
        if(!isNull)
        {
          wait();
        }
        this.name=name;
        Thread.sleep(10);
        this.sex=sex;
        isNull=false;
        notify();
    }

    //輸出數(shù)據(jù)
    public synchronized void print() throws InterruptedException {
        if(isNull)
        {
            wait();
        }
        System.out.println(name+"---"+sex);
        isNull=true;
        notify();
    }
}
//消費者
public class consumer implements Runnable{
   shareSource s=null;

    public consumer(shareSource s) {
        this.s = s;
    }

    @Override
    public void run() {
        for(int i=0;i<500;i++)
        {
            try {
                s.print();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }

    }
            }

//生產(chǎn)者
public class producer implements Runnable{
    shareSource s=null;

    public producer(shareSource s) {
        this.s = s;
    }

    @Override
    public void run() {
        for(int i=0;i<50;i++)
        {
            if(i%2==0)
            {
                try {
                    s.add("李兵","男");
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }

            }
            else{

                try {
                    s.add("趙瑩","女");
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            }
        }

    }
//測試類
public class testThread {
    public static void main(String[] args) {
        shareSource s=new shareSource();
        producer pp=new producer(s);
        Thread  p=new Thread(pp);
        consumer cc=new consumer(s);
        Thread c=new Thread(cc);
        p.start();
        c.start();

    }
}

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

相關閱讀更多精彩內容

  • 進程和線程 進程 所有運行中的任務通常對應一個進程,當一個程序進入內存運行時,即變成一個進程.進程是處于運行過程中...
    勝浩_ae28閱讀 5,260評論 0 23
  • 進程和線程 進程 所有運行中的任務通常對應一個進程,當一個程序進入內存運行時,即變成一個進程.進程是處于運行過程中...
    小徐andorid閱讀 2,995評論 3 53
  • ??一個任務通常就是一個程序,每個運行中的程序就是一個進程。當一個程序運行時,內部可能包含了多個順序執(zhí)行流,每個順...
    OmaiMoon閱讀 1,809評論 0 12
  • Java-Review-Note——4.多線程 標簽: JavaStudy PS:本來是分開三篇的,后來想想還是整...
    coder_pig閱讀 1,779評論 2 17
  • 我現(xiàn)在幾乎能跟著太陽的時間走?,F(xiàn)在困了,在硬挺著打字!早晨四點多就醒了,起來做事!中午睡15-30分鐘,感覺很好!
    小魚的理想家閱讀 96評論 0 0

友情鏈接更多精彩內容