轉載請注明出處:http://www.lxweimin.com/p/8673e2b23a4e
1.單例設計模式(掌握)
* 單例設計模式:保證類在內存中只有一個對象。
- 如何保證類在內存中只有一個對象呢?
- (1)控制類的創建,不讓其他類來創建本類的對象。private
- (2)在本類中定義一個本類的對象。Singleton s;
- (3)提供公共的訪問方式。 public static Singleton getInstance(){return s}
餓漢式和懶漢式的區別:
餓漢式:類一加載就生成對象。安全,效率高。相對懶漢式會在未使用之前就占用內存。
懶漢式:存在線程安全漏洞,可能會創建多個對象,可以利用同步解決,但是效率會變低。
- 單例寫法兩種:
- (1)餓漢式 開發用這種方式。
//餓漢式 class Singleton { //1,私有構造函數 private Singleton(){} //2,創建本類對象 private static Singleton s = new Singleton(); //3,對外提供公共的訪問方法 public static Singleton getInstance() { return s; } public static void print() { System.out.println("11111111111"); } }
- (2)懶漢式 面試寫這種方式。多線程的問題?
//懶漢式,單例的延遲加載模式 class Singleton { //1,私有構造函數 private Singleton(){} //2,聲明一個本類的引用 private static Singleton s; //3,對外提供公共的訪問方法 public static Singleton getInstance() { if(s == null) //線程1,線程2 s = new Singleton(); return s; } public static void print() { System.out.println("11111111111"); } }
- (3)第三種格式
class Singleton { private Singleton() {} public static final Singleton s = new Singleton();//final是最終的意思,被final修飾的變量不可以被更改 }
2.Runtime類
- Runtime類是一個單例類
Runtime r = Runtime.getRuntime(); //r.exec("shutdown -s -t 300"); //300秒后關機 r.exec("shutdown -a");
3.Timer(掌握)
* Timer類:計時器
public class Demo5_Timer {
/**
* @param args
* 計時器
* @throws InterruptedException
*/
public static void main(String[] args) throws InterruptedException {
Timer t = new Timer();
t.schedule(new MyTimerTask(), new Date(114,9,15,10,54,20),3000);
while(true) {
System.out.println(new Date());
Thread.sleep(1000);
}
}
}
class MyTimerTask extends TimerTask {
@Override
public void run() {
System.out.println("起床背英語單詞");
}
}
4.兩個線程間的通信(掌握)
- 1.什么時候需要通信
- 多個線程并發執行時, 在默認情況下CPU是隨機切換線程的
- 如果我們希望他們有規律的執行, 就可以使用通信, 例如每個線程執行一次打印
- 2.怎么通信
- 如果希望線程等待, 就調用wait()
- 如果希望喚醒等待的線程, 就調用notify();
- 這兩個方法必須在同步代碼中執行, 并且使用同步鎖對象來調用
5.三個或三個以上間的線程通信
- 多個線程通信的問題
- notify()方法是隨機喚醒一個線程
- notifyAll()方法是喚醒所有線程
- JDK5之前無法喚醒指定的一個線程
- 如果多個線程之間通信, 需要使用notifyAll()通知所有線程, 用while來反復判斷條件
6.JDK1.5的新特性互斥鎖(掌握)
- 1.同步
- 使用ReentrantLock類的lock()和unlock()方法進行同步
- 2.通信
- 使用ReentrantLock類的newCondition()方法可以獲取Condition對象
- 需要等待的時候使用Condition的await()方法, 喚醒的時候用signal()方法
- 不同的線程使用不同的Condition, 這樣就能區分喚醒的時候找哪個線程了
7.線程組的概述和使用(了解)
- A:線程組概述
- Java中使用ThreadGroup來表示線程組,它可以對一批線程進行分類管理,Java允許程序直接對線程組進行控制。
- 默認情況下,所有的線程都屬于主線程組。
- public final ThreadGroup getThreadGroup()//通過線程對象獲取他所屬于的組
- public final String getName()//通過線程組對象獲取他組的名字
- 我們也可以給線程設置分組
- 1,ThreadGroup(String name) 創建線程組對象并給其賦值名字
- 2,創建線程對象
- 3,Thread(ThreadGroup?group, Runnable?target, String?name)
- 4,設置整組的優先級或者守護線程
8.線程的五種狀態(掌握)
- 看圖說話
- 新建,就緒,運行,阻塞,死亡
這里寫圖片描述
9.線程池的概述和使用(了解)
- A:線程池概述
- 程序啟動一個新線程成本是比較高的,因為它涉及到要與操作系統進行交互。而使用線程池可以很好的提高性能,尤其是當程序中要創建大量生存期很短的線程時,更應該考慮使用線程池。線程池里的每一個線程代碼結束后,并不會死亡,而是再次回到線程池中成為空閑狀態,等待下一個對象來使用。在JDK5之前,我們必須手動實現自己的線程池,從JDK5開始,Java內置支持線程池
作用:當程序中要很多生存期很短的線程時,為了不頻繁的創建線程,可以使用線程池,
因為線程池里面的線程在代碼結束后,并不會死亡,而是再次回到線程池中成為空閑狀態,
等待下一個對象來使用(最后一定要關)。
- 程序啟動一個新線程成本是比較高的,因為它涉及到要與操作系統進行交互。而使用線程池可以很好的提高性能,尤其是當程序中要創建大量生存期很短的線程時,更應該考慮使用線程池。線程池里的每一個線程代碼結束后,并不會死亡,而是再次回到線程池中成為空閑狀態,等待下一個對象來使用。在JDK5之前,我們必須手動實現自己的線程池,從JDK5開始,Java內置支持線程池
- B:內置線程池的使用概述
- JDK5新增了一個Executors工廠類來產生線程池,有如下幾個方法
- public static ExecutorService newFixedThreadPool(int nThreads)
- public static ExecutorService newSingleThreadExecutor()
- 這些方法的返回值是ExecutorService對象,該對象表示一個線程池,可以執行Runnable對象或者Callable對象代表的線程。它提供了如下方法
- Future<?> submit(Runnable task)
- <T> Future<T> submit(Callable<T> task)
- 使用步驟:
- 創建線程池對象
- 創建Runnable實例
- 提交Runnable實例
- 關閉線程池
- JDK5新增了一個Executors工廠類來產生線程池,有如下幾個方法
10.多線程程序實現的方式3(了解)
* 提交的是Callable
多線程程序實現的方式3的好處和弊端
* 好處:
* 可以有返回值
* 可以拋出異常
* 弊端:
* 代碼比較復雜,所以一般不用
11.簡單工廠模式概述和使用(了解)
- A:簡單工廠模式概述
- 又叫靜態工廠方法模式,它定義一個具體的工廠類負責創建一些類的實例
- B:優點
- 客戶端不需要在負責對象的創建,從而明確了各個類的職責
- C:缺點
- 這個靜態工廠類負責所有對象的創建,如果有新的對象增加,或者某些對象的創建方式不同,就需要不斷的修改工廠類,不利于后期的維護
- D:案例演示
- 動物抽象類:public abstract Animal { public abstract void eat(); }
- 具體狗類:public class Dog extends Animal {}
- 具體貓類:public class Cat extends Animal {}
- 開始,在測試類中每個具體的內容自己創建對象,但是,創建對象的工作如果比較麻煩,就需要有人專門做這個事情,所以就知道了一個專門的類來創建對象。
12.工廠方法模式的概述和使用(了解)
- A:工廠方法模式概述
- 工廠方法模式中抽象工廠類負責定義創建對象的接口,具體對象的創建工作由繼承抽象工廠的具體類實現。
- B:優點
- 客戶端不需要在負責對象的創建,從而明確了各個類的職責,如果有新的對象增加,只需要增加一個具體的類和具體的工廠類即可,不影響已有的代碼,后期維護容易,增強了系統的擴展性
- C:缺點
- 需要額外的編寫代碼,增加了工作量
13.GUI(如何創建一個窗口并顯示)
-
Graphical User Interface(圖形用戶接口)。
Frame f = new Frame(“my window”); f.setLayout(new FlowLayout());//設置布局管理器 f.setSize(500,400);//設置窗體大小 f.setLocation(300,200);//設置窗體出現在屏幕的位置 f.setIconImage(Toolkit.getDefaultToolkit().createImage("qq.png")); f.setVisible(true);
14.GUI(布局管理器)
- FlowLayout(流式布局管理器)
- 從左到右的順序排列。
- Panel默認的布局管理器。
- BorderLayout(邊界布局管理器)
- 東,南,西,北,中
- Frame默認的布局管理器。
- GridLayout(網格布局管理器)
- 規則的矩陣
- CardLayout(卡片布局管理器)
- 選項卡
- GridBagLayout(網格包布局管理器)
- 非規則的矩陣
15.GUI(窗體監聽)
Frame f = new Frame("我的窗體");
//事件源是窗體,把監聽器注冊到事件源上
//事件對象傳遞給監聽器
f.addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent e) {
//退出虛擬機,關閉窗口
System.exit(0);
}
});
16.適配器設計模式(掌握)
- a.什么是適配器
- 在使用監聽器的時候, 需要定義一個類事件監聽器接口.
- 通常接口中有多個方法, 而程序中不一定所有的都用到, 但又必須重寫, 這很繁瑣.
- 適配器簡化了這些操作, 我們定義監聽器時只要繼承適配器, 然后重寫需要的方法即可.
- b.適配器原理
- 適配器就是一個類, 實現了監聽器接口, 所有抽象方法都重寫了, 但是方法全是空的.
- 適配器類需要定義成抽象的,因為創建該類對象,調用空方法是沒有意義的
- 目的就是為了簡化程序員的操作, 定義監聽器時繼承適配器, 只重寫需要的方法就可以了.
17.需要知道的
- 事件處理
- 事件: 用戶的一個操作
- 事件源: 被操作的組件
- 監聽器: 一個自定義類的對象, 實現了監聽器接口, 包含事件處理方法,把監聽器添加在事件源上, 當事件發生的時候虛擬機就會自動調用監聽器中的事件處理方法
18.面試題
1,在同步代碼塊中,用哪個對象鎖,就用哪個對象調用wait方法
2,為什么wait方法和notify方法定義在Object這類中?
因為鎖對象可以是任意對象,Object是所有的類的基類,所以wait方法和notify方法需要定義在Object這個類中
3,sleep方法和wait方法的區別?
a,sleep方法必須傳入參數,參數就是時間,時間到了自動醒來
wait方法可以傳入參數也可以不傳入參數,傳入參數就是在參數的時間結束后等待,不傳入參數就是直接等待
b,sleep方法在同步函數或同步代碼塊中,不釋放鎖,睡著了也抱著鎖睡
wait方法在同步函數或者同步代碼塊中,釋放鎖