---------------------- ASP.Net+Android+IOS開發、.Net培訓、期待與您交流! ----------------------
進程:直譯就是正在進行中的程序。
線程:就是進程中一個負責程序執行的控制單元
一個進程可以有多執行路徑,稱之爲多線程
一個進程至少有一個線程。
多線程的好處: 解決了部分同時運行的問題
多線程的弊端: 線程太多會倒效率的降低
其實應用程序的執行都是cpu在做着快速的切換完成的 這個切換是隨機的。
如果創建一個線程?
方式一 繼續Thread類
步驟 :1 定義一個類繼續Thread類
2 覆蓋Thread類中的run方法。
3 直接創建Thread的子類對象創建線程。
例如:
class Demo extends Thread
{
private String name;
Demo(String name)
{
super(name);
// this.name = name;
}
public void run()
{
for (int x = 0; x < 10; x++)
{
// for(int y=-9999999; y<999999999; y++){}
System.out.println(name + "....x=" + x + ".....name="
+ Thread.currentThread().getName());
}
}
}
class ThreadDemo2
{
public static void main(String[] args)
{
Thread t1 = new Thread();
Demo d1 = new Demo("旺財");
Demo d2 = new Demo("xiaoqiang");
d1.start();// 開啓線程,調用run方法。
d2.start();
System.out.println("over...." + Thread.currentThread().getName());
}
}
jvm創建的主線程的任務都是定義在了主函數中。
run()方法中定義就是線程要運行的人物代碼。
創建時就明確了名稱的定義
Thread 通過getName()來獲取線程的名稱。Thread編號從0開始。
主線程的名字就是main。
創建線程的第二種方式:實現Runnable接口
1 定義類實現Runnable接口
2 覆蓋接口中的run方法,將線程的人物代碼封裝在run()中
3通過Thread類創建線程對象,並將Runnable接口的子類對象作爲構造函數的參數進行傳遞
例如:
class Bank
{
private int sum;
// private Object obj = new Object();
public synchronized void add(int num)// 同步函數
{
// synchronized(obj)
// {
sum = sum + num;
// -->
try {
Thread.sleep(10);
} catch (InterruptedException e) {
}
System.out.println("sum=" + sum);
// }
}
}
class Cus implements Runnable
{
private Bank b = new Bank();
public void run()
{
for (int x = 0; x < 3; x++)
{
b.add(100);
}
}
}
class BankDemo
{
public static void main(String[] args)
{
Cus c = new Cus();
Thread t1 = new Thread(c);
Thread t2 = new Thread(c);
t1.start();
t2.start();
}
}
爲什麼這樣做?因爲線程的任務都封裝在Runnable接口子類對象中的方法中,所以要在線程對象創建時就必須明確要運行的任務。
4 調用線程對象的start方法開啓線程。
Runnable她的出現僅僅是將線程的任務進行了對象的封裝。
實現了Runnable接口的好處:
1 將線程的任務從線程的子類中分離出來,進行了單獨的封裝
按照了面向對象的思想將任務封裝成對象
2 避免了java單繼承的侷限性。
創建線程的第二種方式最常用。
多次啓動一個線程是非法的。
線程安全問題產生的原因
1 多個線程在操作共享數據
2 操作共享數據的線程代碼有多條。
當一個線程在執行操作共享數據的多條代碼過程中,其他線程參與了運算
就會導致線程安全問題的產生。
解決思路:
就是將多條操作共享數據的線程代碼封裝起來,當有線程在執行這些代碼的時候,
其他線程是不可以參與運算的
必須要當前線程把這些代碼都執行完畢後,其他線程纔可以參與運算。
在java中,用同步代碼塊就是可以解決這個問題
同步代碼塊的格式
synchronized(對象){
需要同步的代碼:
}
同步的好處就是: 解決了線程安全的問題
弊端就是:相對降低了效率,因爲同步的外線程的都會判斷同步鎖。
同步的前提:必須有多個線程並使用同一個鎖。
同步函數和同步代碼的鎖是this。
同步函數和同步代碼塊的區別:
同步代碼塊的鎖是任意對象
同步函數的鎖是固定的 this
建議使用同步代碼。
靜態的同步函數使用的鎖是 該函數所屬字節碼文件對象, 可以用getClass方法獲取,也可以用當前類名.class表示。
//懶漢式 面試經常面試到的
class single{
private static finall Single s=null;
privat single{
}
public static Single getInstance(){
if(s==null){ //第一次判斷是爲了提高效率
synchronized(Single。class){//解決安全隱患。
if(s==null){
s=new Single();
}
}
}
return s;
}
}
線程常見的問題之一:死鎖。
同步的嵌套。
/*
死鎖:常見情景之一:同步的嵌套。
*/
class Ticket implements Runnable
{
private int num = 100;
Object obj = new Object();
boolean flag = true;
public void run()
{
if (flag)
while (true)
{
synchronized (obj)
{
show();
}
}
else
while (true)
this.show();
}
public synchronized void show()
{
synchronized (obj)
{
if (num > 0)
{
try {
Thread.sleep(10);
} catch (InterruptedException e) {
System.out.println(Thread.currentThread().getName()
+ ".....sale...." + num--);
}
}
}
}
class DeadLockDemo
{
public static void main(String[] args)
{
Ticket t = new Ticket();
// System.out.println("t:"+t);
Thread t1 = new Thread(t);
Thread t2 = new Thread(t);
t1.start();
try {
Thread.sleep(10);
} catch (InterruptedException e) {
}
t.flag = false;
t2.start();
}
}
}
等待 喚醒機制
涉及的方法。
1 wait() 讓線程處於凍結狀態,被wait的線程會被存儲到線程池中。
2 notify()喚醒線程池中的一個任意線程
3 notifyAll()喚醒線程池中的所有線程。
這些方法都必須定義在同步中。
因爲這些方法是用於操作線程狀態的方法
必須要明確到底操作的是哪個鎖上的線程。
爲什麼操作線程的方法wait notify notifyAll定義在了object類中?
因爲這些方法是監視器的方法。監視器其實就是鎖。
jdk 1.5出現了 lock 替代了synchronized。
jdk 1.5出現以後將同步和鎖封裝成了對象,並將操作的隱式定義到了該對象中,將隱式動作變成了顯示動作。
lock接口:出現替代了同步代碼塊或者同步函數。將同步代碼的隱式鎖操作變成了顯示鎖操作。
同時更爲靈活可以一個鎖上加上多組監視器
lock():獲取鎖
unlock():釋放鎖,通常需要定義finally代碼塊中。
Condition接口: 出行替代了Object中的wait notify notifyAll 方法。
將這些監視器方法單獨進行了封裝,變成了Condition監視器對象。
可以任意鎖緊組合。
await();
signal();
signalAll();
wait 和sleep 區別
1,wait可以指定時間也可以不指定。
sleep必須要指定時間
2 在同步中時,多cpu的執行權和鎖的處理不同
wait:釋放行權,釋放鎖
sleep:釋放執行權,不釋放鎖。
我的總結:Java線程是Java語言中一個非常重要的部分通過使用Java5線程新特徵的API,可以很容易的做出複雜的多線程程序。
---------------------- (科技新時代)申請入駐搜狐公衆平臺,特此聲明----------------------