如何實(shí)現(xiàn)Java線程安全問題
這篇文章主要介紹了如何實(shí)現(xiàn)Java線程安全問題,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
解決線程安全問題的第一種方案:使用同步代碼塊
格式:
synchronized(鎖對象) {
可能會出現(xiàn)線程安全問題的代碼(訪問了共享數(shù)據(jù)的代碼)
}
注意:代碼塊中的鎖對象,可以是任意對象,但必須保證多個線程之間使用的是同一個
鎖對象的作用是把同步代碼塊鎖住,同一時間只能讓一個線程在同步代碼塊中執(zhí)行
package com.fgy.demo02;
/**
* 實(shí)現(xiàn)賣票案例
*/
public class RunnableImpl implements Runnable {
private int ticket = 100;
Object obj = new Object();
@Override
public void run() {
while (true) {
synchronized (obj) {
if (ticket > 0) {
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + "正在買第" + ticket + "張票");
ticket--;
}
}
}
}
}
package com.fgy.demo02;
public class Demo01Ticket {
public static void main(String[] args) {
RunnableImpl run = new RunnableImpl();
new Thread(run).start();
new Thread(run).start();
new Thread(run).start();
}
}

解決線程安全問題的第二種方案:使用同步方法
使用步驟:
1.把訪問了共享數(shù)據(jù)的代碼抽取出來,放到一個方法中
2.在方法上添加synchronized修飾符
格式:
修飾符 synchronized 返回值類型 方法名(...) {
可能會出現(xiàn)線程安全問題的代碼(訪問了共享數(shù)據(jù)的代碼)
}
同步方法的鎖對象是:this
靜態(tài)同步方法的鎖對象不能是this,因?yàn)閠his是創(chuàng)建對象后產(chǎn)生的,靜態(tài)方法優(yōu)先于對象
靜態(tài)方法的鎖對象是本類的class文件對象
package com.fgy.demo03;
/**
* 實(shí)現(xiàn)賣票案例
*/
public class RunnableImpl implements Runnable {
private int ticket = 100;
@Override
public void run() {
while (true) {
payTicket();
}
}
public synchronized void payTicket() {
if (ticket > 0) {
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + "正在買第" + ticket + "張票");
ticket--;
}
}
}
解決線程安全問題的第三種方案:使用lock鎖
使用步驟:
1.在成員位置創(chuàng)建ReenterantLock對象
2.在可能出現(xiàn)安全問題的代碼前調(diào)用Lock接口中的方法lock()獲取鎖
3.在可能出現(xiàn)安全問題的代碼后調(diào)用Lock接口中的方法unlock()釋放鎖
package com.fgy.demo04;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
/**
* 實(shí)現(xiàn)賣票案例
*/
public class RunnableImpl implements Runnable {
private int ticket = 100;
Lock l = new ReentrantLock();
/*@Override
public void run() {
while (true) {
l.lock();
if (ticket > 0) {
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + "正在買第" + ticket + "張票");
ticket--;
}
l.unlock();
}
}*/
@Override
public void run() {
while (true) {
l.lock();
if (ticket > 0) {
try {
Thread.sleep(100);
System.out.println(Thread.currentThread().getName() + "正在買第" + ticket + "張票");
ticket--;
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
// 無論程序是否發(fā)生異常都會釋放鎖
l.unlock();
}
}
}
}
}
以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
IntelliJ IDEA JRebel 安裝使用圖文教程(熱部署插件)
IDEA 全稱 IntelliJ IDEA,是java語言開發(fā)的集成環(huán)境,IntelliJ在業(yè)界被公認(rèn)為最好的java開發(fā)工具之一。這篇文章主要介紹了IntelliJ IDEA 熱部署插件JRebel 安裝使用圖文教程,需要的朋友可以參考下2018-03-03
Spring MVC中處理ajax請求的跨域問題與注意事項(xiàng)詳解
跨域問題是我們大家在開發(fā)中會經(jīng)常遇到的一個問題,所以下面這篇文章主要給大家介紹了關(guān)于Spring MVC中處理ajax請求的跨域問題與注意事項(xiàng)的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),需要的朋友可以參考借鑒,下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧。2017-11-11
idea運(yùn)行main方法或Test避免編譯整個應(yīng)用的實(shí)現(xiàn)方法
這篇文章主要介紹了idea運(yùn)行main方法或Test避免編譯整個應(yīng)用的方法,具有很好的參考價(jià)值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2023-04-04
springmvc+shiro+maven 實(shí)現(xiàn)登錄認(rèn)證與權(quán)限授權(quán)管理
Shiro 是一個 Apache 下的一開源項(xiàng)目項(xiàng)目,旨在簡化身份驗(yàn)證和授權(quán),下面通過實(shí)例代碼給大家分享springmvc+shiro+maven 實(shí)現(xiàn)登錄認(rèn)證與權(quán)限授權(quán)管理,感興趣的朋友一起看看吧2017-09-09
Jpa 實(shí)現(xiàn)自動更新表中的創(chuàng)建日期和修改時間
這篇文章主要介紹了Jpa 實(shí)現(xiàn)自動更新表中的創(chuàng)建日期和修改時間,具有很好的參考價(jià)值,希望對大家有所幫助。一起跟隨小編過來看看吧2021-01-01
java如何實(shí)現(xiàn)圖片轉(zhuǎn)化為數(shù)據(jù)流
這篇文章主要介紹了java如何實(shí)現(xiàn)圖片轉(zhuǎn)化為數(shù)據(jù)流,具有很好的參考價(jià)值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2022-01-01

