多線程
線程概念
進程: 就是計算機中正在運行的程序所在內存的區域.
線程: 源代碼的執行路徑,可以看成是進行中的子程序.
注意:JVM是多線程虛擬機,最直觀的看到一條執行路徑,一條回收垃圾.
線程的好處: 提高的程序的運行效率,可以保證多個程序一起運行
用Thread類創建線程
1) 繼承Thread類.
2) 重寫Thread類中的run方法, 這時類已經是線程類了.
3) 建立線程類的對象,其實就是創建一個線程.
4) 調用線程start方法.
a 開啓線程.
b JVM調用線程run方法.
線程的特點:
1) CPU控制線程的執行.
2) CPU進行線程中的切換,隨機切換,無法控制.
用Runnable接口創建多線程
1) 建立實現Runnable接口的實現類.
2) 重寫Run方法.(public Thread(Runnable target))
3) 創建Thread類對象,傳遞Runnable的子類對象.
4) 調用Thread類中的start方法.
5) start方法開啓線程,並調用Runnable接口子類對象中的Run方法.
兩種多線程創建的區別(繼承Thread類和實現Runnable接口區別)
1) 實現Runnable接口的方式,可以共享數據.
2) 避免了繼承的侷限性.
線程安全隱患
1) 數據被多線程操作就容易出現安全隱患
2) 數據是多線程的共享數據
3) 解決安全問題前提:是不是多線程的程序和是不是持有同一把鎖.
synchronized關鍵字(同步)
應用在線程操作的共享數據.
格式:
synchronized (參數) {}
參數:
1) 非靜態的函數中所用的鎖是this
2) 靜態裏面用得是字節碼class文件,類名.class
死鎖問題
代碼:
/*
死鎖
*/
class _dead implements Runnable //實現Runnable接口
{
boolean x = false;
public void run()
{
while (true)
{
if (x)
{
synchronized (_locka.a)
{
System.out.println("if>>>locka");
synchronized (_lockb.b)
{
System.out.println("if>>>lockb");
}
}
}
else
{
synchronized (_lockb.b)
{
System.out.println("else....lockb");
synchronized (_locka.a)
{
System.out.println("else ... locka");
}
}
}
}
}
}
class _locka
{
public static _locka a = new _locka();
}
class _lockb
{
public static _lockb b = new _lockb();
}
class Test2
{
public static void main(String[] args)
{
_dead d = new _dead();
Thread t = new Thread(d);
t.start();
_dead d1 = new _dead();
d1.x=true;
Thread t1 = new Thread(d1);
t1.start();
}
}
Thread方法常用參數介紹
run負責線程中運行的代碼
Thread(String name),構造的時候,傳遞線程名
getName()獲取線程名
setName()設置線程名
Thread.currentThread().getName()獲取線程名,在非Thread子類中使用
start()開啓線程,JVM調用線程的run方法
安全高效的懶漢式
/*
單例模式中,懶漢不安全
寫一個,你認爲安全的,效率較高的單例模式,要求懶漢
*/
class Single
{
private Single(){}
private static Single s = null; //先給s變量賦null值
public static Single show()
{ //通過雙if判斷是否爲null
if (s== null)
{
if (s ==null)
{
synchronized (Single.class) //靜態方法同步指向class文件
{
s = new Single();
}
}else
{
return s;
}
}
return s;
}
}
class Test implements Runnable
{
public void run()
{
while (true)
{
Single s = Single.show();
System.out.println(s);
}
}
}
class Test4
{
public static void main(String[] args)
{
Test t = new Test();
Thread t1 = new Thread(t);
t1.start();
}
}