1>多線程的 實現方式 繼承Thread類 或者 實現 Runnable 接口
2>出現線程安全的原因(主要講解 同步鎖)
線程 操作共性數據的多條代碼 分開執行,就會引起線程安全問題(關鍵點:存在共性數據,操作共性數據的多條代碼被分開)
解決方案:保證 操作共性數據的多條代碼在同一時間段內 只有一個線程在執行,執行期間,不允許其他線程進入。
解決問題的方式:
java提供瞭解決方案,就是同步機制。
代碼體現:同步代碼塊。
synchronized(對象)//對象可以是任意對象。
{
需要被同步封裝的語句。
}
同步的好處:
解決了多線程的安全問題。
同步前提:
1,必須要有兩個或者兩個以上的線程。
2,多個線程必須使用同一個鎖。
同步的弊端:
降低運行效率,對資源是一種消耗。
class Ticket implements Runnable{
private int tickets = 10;
private Object obj = new Object();
public void run(){
while(tickets > 0){
try {
synchronized(obj){
Thread.sleep(100);
if(tickets>0)
System.out.println(Thread.currentThread().getName()+" "+tickets--);
}
} catch (InterruptedException e) {
throw new RuntimeException();
}
}
}
}
public class TicketDemo {
public static void main(String[] args) {
Ticket t = new Ticket();
Thread t1 = new Thread(t);
Thread t2 = new Thread(t);
Thread t3 = new Thread(t);
Thread t4 = new Thread(t);
t1.start();
t2.start();
t3.start();
t4.start();
}
}
將同步代碼塊 提取出來 封裝爲一個方法,同時在該方法 同步(添加synchronized關鍵字),於是就出現了同步函數。
同步代碼塊的鎖 是 private Object obj = new Object();
同步函數用的鎖 是 this。
同步函數和同步代碼塊的區別:
同步函數使用的鎖是固定的 this。
同步代碼塊可以指定任意的對象作爲鎖。
一般開發常用同步代碼塊。
靜態同步函數鎖使用的鎖是:所屬類的字節碼文件對象 寫法 類名.class
驗證 使用的 鎖 是什麼的 方法如下,將同步代碼塊的鎖
class Ticket implements Runnable
{
private int ticks = 100;
Object obj = new Object();
boolean flag = true;
public void run()
{
if(flag)
while(true)
{
synchronized(this)
{
if(ticks>0)
{
try{Thread.sleep(10);}catch(InterruptedException e){}
System.out.println(Thread.currentThread().getName()+"..code.."+ticks--);
}
}
}
else
while(true)
show();
}
public synchronized void show()
{
if(ticks>0)
{
try{Thread.sleep(10);}catch(InterruptedException e){}
System.out.println(Thread.currentThread().getName()+"..show funciton.."+ticks--);
}
}
}
class ThisLockDemo
{
public static void main(String[] args)
{
Ticket t = new Ticket();
Thread t1 = new Thread(t);
Thread t2 = new Thread(t);
t1.start();
try{Thread.sleep(10);}catch(Exception e){}
t.flag = false;
t2.start();
}
}
3>關於 死鎖的 一個例子
class DeadLock implements Runnable{
private static Object lockA = new Object();
private static Object lockB = new Object();
private boolean flag;
DeadLock(boolean flag){
this.flag = flag;
}
public void run() {
if(flag){
while(true){
synchronized (lockA) {
System.out.println(" if ------- lockA ");
synchronized (lockB) {
System.out.println(" if ------- lockB ");
}
}
}
}else{
while(true){
synchronized (lockB) {
System.out.println(" else ------- lockB ");
synchronized (lockA) {
System.out.println(" else ------- lockA ");
}
}
}
}
}
}
public class DeadLockDemo {
public static void main(String[] args) {
DeadLock t1 = new DeadLock(true);
DeadLock t2 = new DeadLock(false);
Thread tt1 = new Thread(t1);
Thread tt2 = new Thread(t2);
tt1.start();
tt2.start();
}
}
注意上面代碼中使用的鎖,是static的,保證t1和t2使用的是相同的 lockA和lockB