重拾java基礎(十八):多執行緒下總結
一、死鎖
1、同步鎖可以解決執行緒安全問題,但是同步鎖會帶來死鎖問題;2、死鎖就是彼此佔用對方的資源,使程式暫停,無法繼續運作下去。 3.死鎖出現的機率 非常小 但是危害非常大。 4.案例: 歐巴馬和普丁一起吃飯,飯菜都上齊了,非常美味,他們非常餓, 開吃吧...但是每個人手裡只有一根筷子...如果沒有人願意共享自 己的筷子,那他們就只能餓著...看著...饞著...留著口水...a. 歐巴馬是一個線程 歐巴馬要吃飯,要普丁的筷子b. 普丁是一個線程 普丁要吃飯,要歐巴馬的筷子c. 巢狀鎖+ 交叉鎖
:8 、執行緒間的通訊
1、在实现线程安全时,程序进入同步代码块后就会自动上锁,直到程序把代码块中的代码执行完后才会进行下步操作。 2、每个对象都有一把锁,那么开锁的方法就被定义到了Object类中; Public final void wait(),让当前线程等待,同时释放锁,直到被再次唤醒。 public final void wait(long timeout),在指定时间内让当前线程等待,同时释放锁, wait()和sleep()都可以让当前线程等待,区别: 1,sleep():释放执行权(等待),不释放锁 2,wait():释放执行权(等待),同时释放锁如果调用的是无参的wait()方法,那锁就一直释放,当前线程一直等待,还需要唤醒。 Object类提供了notify()方法用来唤醒某个被wait()的锁,也就是唤醒线程细节: wait()和notify()方法都是操作锁的,而锁存在于同步中,也就是说这两个方法必须出现在同步中(同步代码块或同步方法)。 同步锁不仅可以解决昨天的线程安全问题,还可以实现线程间的通信3、线程间的通信 例子:一个线程输出10次1,一个线程输出10次2,观察执行结果 现要求交替输出“1 2 1 2 1 2...” 或 “2 1 2 1 2 1... public class Testnotif1 extends Thread{ public void run(){ for (int i = 0; i < 10; i++) { synchronized (MyLocd.o1) { System.out.println(1); MyLocd.o1.notify(); try { MyLocd.o1.wait(); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } } } package cn.itcast.Thread; public class Testnotif2 extends Thread { public void run() { for (int i = 0; i < 10; i++) { synchronized (MyLocd.o1) { System.out.println(2); MyLocd.o1.notify(); try { MyLocd.o1.wait(); } catch (InterruptedException e) { e.printStackTrace(); } } } }} package cn.itcast.Thread; public class Testnotif { public static void main(String[] args) { // TODO Auto-generated method stub Testnotif1 f1=new Testnotif1(); Testnotif2 f2=new Testnotif2(); f1.start(); f2.start(); }}线程之间是互相独立,这个通信指的是线程之间互相打个招呼,控制CPU 的随机性notify()方法 叫醒正在休息的线程 Object类该方法只能叫醒跟他共用一把锁(这把锁类似于中间人)的那个线程
生成消費者模式
線間通訊 經典案例
public class MyLocd { public static Object o1=new Object(); public static Object o2=new Object();}package cn.itcast.Thread; public class TestHaizi extends Thread{ public void run(){ while(true){ synchronized (Kuang.al) { if (Kuang.al.size() <= 0) { try { Kuang.al.wait(); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } Kuang.al.remove(0); Kuang.al.notify(); System.out.println("孩子吃了一个,框里还有" + Kuang.al.size() + "个水果!"); try { Thread.sleep(1000); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } }}package cn.itcast.Thread; public class Testnongfu extends Thread{ public void run(){ while(true){ synchronized (Kuang.al) { if (Kuang.al.size() >= 30) { try { Kuang.al.wait(); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } Kuang.al.add(1); Kuang.al.notify(); System.out.println("农夫在框里放了一个,框里总共" + Kuang.al.size() + "个水果!"); try { Thread.sleep(500); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } }}package cn.itcast.Thread; public class TestNongfuHaozi { public static void main(String[] args) { // TODO Auto-generated method stub Testnongfu t1=new Testnongfu(); TestHaizi t2=new TestHaizi(); t1.start(); t2.start(); }}
三、執行緒狀態
設計模式*********************只能创建出来一个对象***************************
//懒汉式
class Single{
private static Single s = null;
private Single(){}
public synchronized static Single getInstance(){
if (s == null){
s = new Single();
}
return s;
}}
//面试时懒汉式出现的几率非常大//饿汉式
public class Singleton{
private static Singleton s = new Singleton ();
private Singleton (){}
public static Singleton getInstance(){
return s;
}
} 懒汉式存在线程安全问题,虽然能解决,但是会造成效率变低,因此开发的时候建议使用饿汉式实现单例设计模式
以上就是重拾java基礎(十八):多線程下總結的內容,更多相關內容請關注PHP中文網(www.php.cn)!