一、多線程
- 工廠模式
- 單利模式
- 代理模式
1.單例模式(Singleton):
注意:
- 單例類只能有一個(gè)實(shí)例
- 單利必須自己創(chuàng)建自己的唯一實(shí)例
- 單例類必須含有所有其他對(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:
currentThread : 顯示當(dāng)前線程
Thread.sleep: 讓線程睡幾毫秒
-
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é)果
- 當(dāng)前線程的名字:main
- 當(dāng)前線程的名稱:Thread-0
- 當(dāng)前線程的名字:C run == tru
- 當(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)]