摘要:靜態(tài)方法的鎖對象是本類的屬性賣票案例出現(xiàn)了線程安全問題賣出了不存在的票和重復(fù)的票解決線程安全問題的二種方案使用同步方法使用步驟把訪問了共享數(shù)據(jù)的代碼抽取出來放到一個方法中在方法上添加修飾符格式定義方法的格式修飾符返回值類型方法名參數(shù)列表可能
靜態(tài)方法的鎖對象是本類的class屬性
package com.itheima.demo08.Synchronized;
/*
賣票案例出現(xiàn)了線程安全問題 賣出了不存在的票和重復(fù)的票 解決線程安全問題的二種方案:使用同步方法 使用步驟: 1.把訪問了共享數(shù)據(jù)的代碼抽取出來,放到一個方法中 2.在方法上添加synchronized修飾符 格式:定義方法的格式 修飾符 synchronized 返回值類型 方法名(參數(shù)列表){ 可能會出現(xiàn)線程安全問題的代碼(訪問了共享數(shù)據(jù)的代碼) }
*/
public class RunnableImpl implements Runnable{
//定義一個多個線程共享的票源 private static int ticket = 100; //設(shè)置線程任務(wù):賣票 @Override public void run() { System.out.println("this:"+this);//this:com.itheima.demo08.Synchronized.RunnableImpl@58ceff1 //使用死循環(huán),讓賣票操作重復(fù)執(zhí)行 while(true){ payTicketStatic(); } } /* 靜態(tài)的同步方法 鎖對象是誰? 不能是this this是創(chuàng)建對象之后產(chǎn)生的,靜態(tài)方法優(yōu)先于對象 靜態(tài)方法的鎖對象是本類的class屬性-->class文件對象(反射) */ public static /*synchronized*/ void payTicketStatic(){ synchronized (RunnableImpl.class){ //先判斷票是否存在 if(ticket>0){ //提高安全問題出現(xiàn)的概率,讓程序睡眠 try { Thread.sleep(10); } catch (InterruptedException e) { e.printStackTrace(); } //票存在,賣票 ticket-- System.out.println(Thread.currentThread().getName()+"-->正在賣第"+ticket+"張票"); ticket--; } } } /* 定義一個同步方法 同步方法也會把方法內(nèi)部的代碼鎖住 只讓一個線程執(zhí)行 同步方法的鎖對象是誰? 就是實現(xiàn)類對象 new RunnableImpl() 也是就是this */ public /*synchronized*/ void payTicket(){ synchronized (this){ //先判斷票是否存在 if(ticket>0){ //提高安全問題出現(xiàn)的概率,讓程序睡眠 try { Thread.sleep(10); } catch (InterruptedException e) { e.printStackTrace(); } //票存在,賣票 ticket-- System.out.println(Thread.currentThread().getName()+"-->正在賣第"+ticket+"張票"); ticket--; } } }
}
package com.itheima.demo08.Synchronized;
/*
模擬賣票案例 創(chuàng)建3個線程,同時開啟,對共享的票進行出售
*/
public class Demo01Ticket {
public static void main(String[] args) { //創(chuàng)建Runnable接口的實現(xiàn)類對象 RunnableImpl run = new RunnableImpl(); System.out.println("run:"+run);//run:com.itheima.demo08.Synchronized.RunnableImpl@58ceff1 //創(chuàng)建Thread類對象,構(gòu)造方法中傳遞Runnable接口的實現(xiàn)類對象 Thread t0 = new Thread(run); Thread t1 = new Thread(run); Thread t2 = new Thread(run); //調(diào)用start方法開啟多線程 t0.start(); t1.start(); t2.start(); }
}
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/75600.html
摘要:線程同步方法是通過鎖來實現(xiàn),每個對象都有切僅有一個鎖,這個鎖與一個特定的對象關(guān)聯(lián),線程一旦獲取了對象鎖,其他訪問該對象的線程就無法再訪問該對象的其他非同步方法對于靜態(tài)同步方法,鎖是針對這個類的,鎖對象是該類的對象。 對實現(xiàn)了Runnable或者Callable接口類,可以通過多線程執(zhí)行同一實例的run或call方法,那么對于同一實例中的局部變量(非方法變量)就會有多個線程進行更改或讀取...
摘要:的關(guān)鍵字中的塊使用關(guān)鍵字進行標(biāo)記。由于每個類只有一個類對象存在于中,因此全局同時只有一個線程能夠進入到同一個類的靜態(tài)同步方法中。同步代碼塊使這種期望成為可能。注意同步代碼塊如何在括號中接受一個對象。相同的實例被傳入兩個不同的線程實例中。 Java的synchronized塊標(biāo)記一個方法或一個代碼塊為同步的。synchronized塊能用于防止出現(xiàn)競態(tài)條件。 Java的synchroni...
摘要:基本使用同步代碼塊同步代碼塊延時秒,方便后面測試作用代碼塊時,方法中的,是指調(diào)用該方法的對象。那么這個時候使用關(guān)鍵字就需要注意了推薦使用同步代碼塊,同步的代碼塊中傳入外部定義的一個變量。 簡述 計算機單線程在執(zhí)行任務(wù)時,是嚴(yán)格按照程序的代碼邏輯,按照順序執(zhí)行的。因此單位時間內(nèi)能執(zhí)行的任務(wù)數(shù)量有限。為了能在相同的時間內(nèi)能執(zhí)行更多的任務(wù),就必須采用多線程的方式來執(zhí)行(注意:多線程模式無法減...
摘要:關(guān)鍵字總結(jié)有個關(guān)鍵字,它們是接下來對其中常用的幾個關(guān)鍵字進行概括。而通過關(guān)鍵字,并不能解決非原子操作的線程安全性。為了在一個特定對象的一個域上關(guān)閉,可以在這個域前加上關(guān)鍵字。是語言的關(guān)鍵字,用來表示一個域不是該對象串行化的一部分。 java 關(guān)鍵字總結(jié) Java有50個關(guān)鍵字,它們是: abstract do implements private ...
摘要:八種基本數(shù)據(jù)類型數(shù)組定義數(shù)組元素類型數(shù)組名元素類型元素個數(shù)和數(shù)組長度元素類型數(shù)組名元素類型元素元素元素元素內(nèi)存的劃分寄存器本地方法區(qū)方法區(qū)棧內(nèi)存存儲局部變量變量所屬作用域一旦結(jié)束變量自動釋放方法進棧局部變量屬于方法所以方法要先進棧堆內(nèi)存存儲 八種基本數(shù)據(jù)類型 byte short int long boolean char float double JAVA數(shù)組 定義數(shù)組 元...
閱讀 651·2021-09-22 10:02
閱讀 6425·2021-09-03 10:49
閱讀 575·2021-09-02 09:47
閱讀 2163·2019-08-30 15:53
閱讀 2940·2019-08-30 15:44
閱讀 910·2019-08-30 13:20
閱讀 1826·2019-08-29 16:32
閱讀 897·2019-08-29 12:46