2020-11-07多線程

一、多線程

  • 工廠模式
  • 單利模式
  • 代理模式

1.單例模式(Singleton):

注意:

  1. 單例類只能有一個(gè)實(shí)例
  2. 單利必須自己創(chuàng)建自己的唯一實(shí)例
  3. 單例類必須含有所有其他對(duì)象提供這一實(shí)例

2.餓漢式單利

public class Calendar {
    private final static Calendar CALENDAR = new Calendar ();
    private Calendar(){};
    public static Calendar getInstance(){
        return CALENDAR;
    }
}

3.懶漢式單利

public class Calendar2 {
   //需要一個(gè)靜態(tài)的成員變量保存咋們的實(shí)例;
    private static Calendar2 CALENDAR2 ;
    //私有化構(gòu)造器,不讓外邊new;
    private Calendar2(){};
    //持有一個(gè)方法,這個(gè)方法能返回內(nèi)存當(dāng)中的實(shí)例;
    public static Calendar2 getInstance(){
        if (CALENDAR2 == null){
            CALENDAR2 = new Calendar2 ();
        }
        return CALENDAR2;
    }
}

4.字符串變成數(shù)組統(tǒng)計(jì)中元素的個(gè)數(shù)

package com.xinzhi;

import java.util.HashMap;
import java.util.Map;

/**
 * @author:荊少奇
 * @create:2020/11/7 16:04
 *
 */
public class Test1 {
    public static void main(String[] args) {
        String content = "hello world hello world aa" + "bb cc db cc ww qq xx xxx";
        //1.先全部搞成小寫(xiě)
        content = content.toLowerCase ();
        //2.字符串搞成數(shù)組
        String[] worlds = content.split ("");
        //3.創(chuàng)建一個(gè)hashmap保存結(jié)果
        Map<String,Object> result = new HashMap<> (16);
        //4.循環(huán)遍歷數(shù)據(jù)一個(gè)單詞一個(gè)單詞看
        for (String word:worlds){
            //看一看hasmap里有沒(méi)有這個(gè)key
            //有的話value+1
            if(result.containsKey (word)){
                result.put (word,(Integer)result.get (word) + 1);
            }else{
                //沒(méi)有的話放進(jìn)去(word+1)
                result.put (word,1);
            }
            //hashmap便利
            for(Map.Entry<String, Object> entry:result.entrySet ()){
                System.out.println (entry.getKey () + "出現(xiàn)" + entry.getValue () + "次了");
            }




        }
    }

}

5.歸并的思想和對(duì)比

package com.xinzhi;

/**
 * @author:荊少奇
 * @create:2020/11/7 15:15
 */
public class Test {

    public static void main(String[] args) {
       int[] arr1 = {1,3,5};
       int[] arr2 = {2,4,6};
       int[] concat = concat (arr1,arr2);

        //把兩個(gè)有序數(shù)組合并成一個(gè)數(shù)組,還有序
        for (int i:concat){
            System.out.println (i + " ");
        }
    }
    private static int[] concat(int[] arr1,int[] arr2) {

        //1.創(chuàng)建一個(gè)新數(shù)組
        int[] temp = new int[arr1.length + arr2.length];

        int left = 0;
        int right = 0;
        int newIndex = 0;

        //退出循環(huán)的機(jī)制
        while (arr1.length != left && arr2.length != right){
            if (arr1[left] > arr2[right]){
                temp[newIndex] = arr2[right];
                right++;
            }else {
                temp[newIndex] = arr1[left];
                left++;
            }
            newIndex++;
        }

        if(arr1.length == left){
            for (int i = right; i < arr2.length;i++){
                temp[newIndex++] = arr2[i];
            }

        }

        if(arr2.length == right){
            for (int i = left; i < arr1.length;i++){
                temp[newIndex++] = arr1[i];
            }

        }

        return temp;
    }
}

二、多進(jìn)程

電腦開(kāi)了很多應(yīng)用程序,一個(gè)程序一個(gè)進(jìn)程

一個(gè)進(jìn)程里邊包含很多線程

Thread:

  1. currentThread : 顯示當(dāng)前線程

  2. Thread.sleep: 讓線程睡幾毫秒

  3. start(): 開(kāi)啟一個(gè)新的線程

    package currentThreadAndThis;
    public class MyThread extends Thread {
        public MyThread(){
            System.out.println("當(dāng)前線程的名字:"+Thread.currentThread().getName());
            System.out.println("當(dāng)前線程的名字:"+this.getName());
        }
        @Override
        public void run(){
            System.out.println("當(dāng)前線程的名字:"+Thread.currentThread().getName()+"   run=="+Thread.currentThread().isAlive());
            System.out.println("當(dāng)前線程的名字:"+this.getName()+"  run=="+this.isAlive());
        }
    }
    
    //啟動(dòng)類
    package currentThreadAndThis;
    public class Run {
        public static void main(String[] args) {
            MyThread myThread=new MyThread();
            //初始化Thread對(duì)象,方便調(diào)用start();
            //此時(shí)myThread作為參數(shù)傳入Thread中,其實(shí)是myThread委托thread去執(zhí)行;
            Thread thread=new Thread(myThread);
            //初始化自定義線程名稱
            thread.setName("C");
            //啟動(dòng)線程
            thread.start();
    
        }
    }
    

運(yùn)行結(jié)果

  1. 當(dāng)前線程的名字:main
  2. 當(dāng)前線程的名稱:Thread-0
  3. 當(dāng)前線程的名字:C run == tru
  4. 當(dāng)前線程的名字:Thread-0 run ==false**

并發(fā)

同時(shí)擁有兩個(gè)或多個(gè)線程,如果程序在單核處理器上運(yùn)行,多個(gè)線程將交替地?fù)Q入或者換出內(nèi)存,這些線程是同時(shí)「 存在 」的,每個(gè)線程都處于執(zhí)行過(guò)程中的某個(gè)狀態(tài),如果運(yùn)行在多核處理器上,此時(shí),程序中每個(gè)線程都將分配到一個(gè)處理器核上,因此可以同時(shí)運(yùn)行。并發(fā)就是多個(gè)線程操作相同的物理機(jī)中的資源,保證其線程安全,合理的利用資源。

三、線程安全問(wèn)題初探(vector和hashTap)

1.異常

頂級(jí)父類:Throwable

Error 錯(cuò)誤 :一旦發(fā)生錯(cuò)誤程序就直接崩潰

Exception 異常:異常分為受查異常和運(yùn)行時(shí)異常

受查異常:手動(dòng)提前處理

運(yùn)行時(shí)異常:手動(dòng)做好檢查

1. 返回異常發(fā)生時(shí)的詳細(xì)信息
public string getMessage();
2. 返回異常發(fā)生時(shí)的簡(jiǎn)要描述
public string toString();
3. 返回異常對(duì)象的本地化信息。使用Throwable的子類覆蓋這個(gè)方法,可以聲稱本地化信息。如果子類沒(méi)有覆蓋該方法,則該方法返回的信息與getMessage()返回的結(jié)果相同
public string getLocalizedMessage();
4. 在控制臺(tái)上打印Throwable對(duì)象封裝的異常信息
public void printStackTrace();

四、Exception:異常

1.處理異常

1. 拋出異常(throws):當(dāng)一個(gè)方法出現(xiàn)錯(cuò)誤引發(fā)異常時(shí),方法創(chuàng)建異常對(duì)象并交付運(yùn)行時(shí)系統(tǒng),異常對(duì)象中包含了異常類型和異常出現(xiàn)時(shí)的程序狀態(tài)等異常信息。

2. 捕獲異常:在方法拋出異常之后,運(yùn)行時(shí)系統(tǒng)將轉(zhuǎn)為尋找合適的異常處理器(exception handler)。潛在的異常處理器是異常發(fā)生時(shí)依次存留在調(diào)用棧中的方法的集合。

try{

}catch{

}

printStackTrace:能打出異常在哪

2.throws和throw有什么不同

位置不同:throws用在函數(shù)上,后面跟的是異常類,可以跟多個(gè)。

throw用在函數(shù)內(nèi),后面跟的是異常對(duì)象。

功能不同:throws用來(lái)聲明異常,讓調(diào)用者知道該功能有可能出現(xiàn)的問(wèn)題,并由調(diào)用者給出預(yù)先的處理方式。

throw拋出具體問(wèn)題的對(duì)象。語(yǔ)句執(zhí)行到throw功能就結(jié)束了,跳轉(zhuǎn)到調(diào)用者。并將具體的問(wèn)題對(duì)象拋給調(diào)用者。

注意:throw語(yǔ)句獨(dú)立存在,下面不要定義其他語(yǔ)句。因?yàn)閳?zhí)行不到throw下面的語(yǔ)句。

3.線程安全

線程安全是指多個(gè)線程在執(zhí)行同一段代碼的時(shí)候采用加鎖機(jī)制,使每次的執(zhí)行結(jié)果和單線程執(zhí)行的結(jié)果都是一樣的,不存在執(zhí)行結(jié)果的二義性。
線程不安全就是不提供加鎖機(jī)制保護(hù),有可能出現(xiàn)多個(gè)線程先后更改數(shù)據(jù)造成所得到的數(shù)據(jù)是臟數(shù)據(jù)

4.解決多線程不安全的問(wèn)題:

synchronizd:同步鎖

1)同步代碼塊:
synchronized(同步鎖)
{
     //方法體
}
(2)同步方法:給多線程訪問(wèn)的成員方法加上synchronized修飾符
public synchronized  void test(){
     //方法體
}

5.String,StringBuilder,StringBuffer

運(yùn)行速度:

StringBuilder > StringBuffer > String

在線程安全上:

StringBuilder是線程不安全的,而StringBuffer是線程安全的

  • String:適用于少量的字符串操作的情況
  • StringBuilder:適用于單線程下在字符緩沖區(qū)進(jìn)行大量操作的情況
  • StringBuffer:適用多線程下在字符緩沖區(qū)進(jìn)行大量操作的情況

[圖片上傳失敗...(image-d54150-1604755558371)]

[圖片上傳失敗...(image-4c8640-1604755558371)]

[圖片上傳失敗...(image-d30ab2-1604755558371)]

[圖片上傳失敗...(image-d8c778-1604755558371)]

?著作權(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)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

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