靜態變量的多線程同步問題

2019獨角獸企業重金招聘Python工程師標準>>> hot3.png

我們先來討論一個問題,一個類的靜態變量當類被多次實例化的時候,靜態變量是否會受影響?首先我們應該清楚的是靜態變量是在類被JVM classloader的時候分配內存,并且是分配在永久區而非堆內存中。

當我們用對象鎖來同步靜態變量的時候,我們來看一個例子。

public interface OrderService {public String getOrderNo();
}

先定義一個接口,獲取一個訂單編號。

public class OrderLockServiceImpl implements OrderService {static int num = 0;
    @Override
    synchronized public String getOrderNo() {SimpleDateFormat date = new SimpleDateFormat("YYYYMMDDHHMMSS");
        return date.format(new Date()) + num++;
    }
}

實現這個接口,并且用對象方法來操作靜態變量。

public class OrderTask implements Runnable {private CountDownLatch latch;
    private OrderService orderService;
    public OrderTask(CountDownLatch latch,OrderService orderService) {this.latch = latch;
        this.orderService = orderService;
    }@Override
    public void run() {try {latch.await();
        } catch (InterruptedException e) {e.printStackTrace();
        }System.out.printf("線程名%s訂單號:%s\n",Thread.currentThread().getName(), orderService.getOrderNo());
    }
}

創建一個線程類,使用CountDownLatch來讓每一個線程都有出現的機會,而不是某一個線程獨占。

public static void main(String[] args) {
   ExecutorService service = Executors.newCachedThreadPool();
   final CountDownLatch latch = new CountDownLatch(1);
   for (int i = 0;i < 10;i++) {OrderService orderService = new OrderLockServiceImpl();
      service.submit(new OrderTask(latch,orderService));
   }latch.countDown();
   service.shutdown();
}

最后實現main方法,用線程池來提交10次線程任務。結果我們發現,這個靜態變量會出現重復(并不是每一次運行都會重復)

線程名pool-2-thread-1訂單號:20180719619072331
線程名pool-2-thread-7訂單號:20180719619072337
線程名pool-2-thread-3訂單號:20180719619072337
線程名pool-2-thread-9訂單號:20180719619072336
線程名pool-2-thread-5訂單號:20180719619072335
線程名pool-2-thread-6訂單號:20180719619072334
線程名pool-2-thread-10訂單號:20180719619072333
線程名pool-2-thread-4訂單號:20180719619072330
線程名pool-2-thread-2訂單號:20180719619072332
線程名pool-2-thread-8訂單號:20180719619072338

由此我們可以斷定,對象鎖并不能保證靜態變量的同步安全。不過如果對象在堆內存中是唯一的,如

public static void main(String[] args) {
   ExecutorService service = Executors.newCachedThreadPool();
   final CountDownLatch latch = new CountDownLatch(1);
   OrderService orderService = new OrderLockServiceImpl();
   for (int i = 0;i < 10;i++) {service.submit(new OrderTask(latch,orderService));
   }latch.countDown();
   service.shutdown();
}

則無論你運行多少次,則靜態變量也一定是同步的。

但是如果我們使用的是類鎖,來改進上面的代碼。

public abstract class AbstractOrderService implements OrderService {static int num = 0;
    public static synchronized String getOrderNo2() {SimpleDateFormat date = new SimpleDateFormat("YYYYMMDDHHMMSS");
        return date.format(new Date()) + num++;
    }@Override
    public String getOrderNo() {return getOrderNo2();
    }
}

抽象類中使用靜態方法,來同步靜態變量。

public class OrderLockServiceImpl extends AbstractOrderService {}

我們在子類中什么都不做,只繼承于抽象類

此時我們即便實例化10個對象

for (int i = 0;i < 10;i++) {OrderService orderService = new OrderLockServiceImpl();
   service.submit(new OrderTask(latch,orderService));
}

其結果依然無論運行多少次,都不會出現重復訂單號,因為這里已經使用了類鎖來同步靜態變量。

轉載于:https://my.oschina.net/u/3768341/blog/1854233

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/451182.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/451182.shtml
英文地址,請注明出處:http://en.pswp.cn/news/451182.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

extends和implements區別

extends和implements區別 extends與implements的不同 1、在類的聲明中&#xff0c;通過關鍵字extends來創建一個類的子類。 一個類通過關鍵字implements聲明自己使用一個或者多個接口。 extends 是繼承某個類, 繼承之后可以使用父類的方法, 也可以重寫父類的方法; imple…

評論:電商巨頭們誰有勇氣曬曬“價格戰”賬單?

摘要&#xff1a;國內電商接二連三上演的“價格戰”&#xff0c;點燃了消費者的購買熱情。在筆者看來&#xff0c;如果有哪個大型電商有勇氣亮出價格戰賬單&#xff0c;那對競爭對手的刺激和打擊效果將非同一般。曬出了賬單后&#xff0c;消費者對購物場所的選擇也將一目了然&a…

The xxx collides with a package/type

前些天發現了一個巨牛的人工智能學習網站&#xff0c;通俗易懂&#xff0c;風趣幽默&#xff0c;忍不住分享一下給大家。點擊跳轉到教程。 當類和包&#xff0c;重名時&#xff0c;包會報錯誤&#xff1a;The package aaa.a collides with a type&#xff1b;類也會報警告&…

Hive 行列轉換

在京東眾多業務中&#xff0c;促銷業務充滿了復雜性和挑戰性&#xff0c;因為業務的靈活性&#xff0c;很多數據都存儲成xml和json格式數據&#xff0c;這就要求下游數據分析師們需要對其做解析后方可使用 。 在眾多操作中 &#xff0c;有一種是需要對數據做行列轉換操作。 數據…

[譯] 論 Rust 和 WebAssembly 對源碼地址索引的極限優化

原文地址&#xff1a;Oxidizing Source Maps with Rust and WebAssembly原文作者&#xff1a;Nick Fitzgerald譯文出自&#xff1a;掘金翻譯計劃本文永久鏈接&#xff1a;github.com/xitu/gold-m…譯者&#xff1a;D-kylinTom Tromey 和我嘗試使用 Rust 語言進行編碼&#xff0…

Java WebService 簡單實例

前些天發現了一個巨牛的人工智能學習網站&#xff0c;通俗易懂&#xff0c;風趣幽默&#xff0c;忍不住分享一下給大家。點擊跳轉到教程。 前言&#xff1a;朋友們開始以下教程前&#xff0c;請先看第五大點的注意事項&#xff0c;以避免不必要的重復操作。 一、準備工作&…

互聯網侵入手機逐鹿背后:追求流量變現能力

摘要&#xff1a;小米聯合創始人黎萬強說&#xff0c;賣出10萬臺得免速死&#xff0c;賣出百萬臺算是得到了一張正式入行的門票。小米是一家新創公司&#xff0c;黎萬強自己說&#xff0c;原本一無所有&#xff0c;作為原創品牌&#xff0c;它選擇了口碑之路&#xff0c;則必須…

java api使用ElastichSearch指南

AggregationBuilders.terms:一段時間內&#xff0c;某個字段取值的數量排名前幾的聚合 / ** param startTime 開始的時間* param endTime 結束的時間* param termAggName term過濾* param fieldName 要做count的字段* param top 返回的數量*/ RangeQueryBuilder actionPeriod …

關于JavaScript的數組隨機排序

昨天了解了一下Fisher–Yates shuffle費雪耶茲隨機置亂算法&#xff0c;現在再來看看下面這個曾經網上常見的一個寫法&#xff1a; function shuffle(arr) { arr.sort(function () { return Math.random() - 0.5; }); } 或者使用更簡潔的 ES6 的寫法&#xff1a; function shu…

通用唯一識別碼UUID

UUID是通用唯一識別碼&#xff08;Universally Unique Identifier&#xff09;的縮寫。UUID 的目的&#xff0c;是讓分布式系統中的所有元素&#xff0c;都能有唯一的辨識資訊&#xff0c;而不需要透過中央控制端來做辨識資訊的指定。如此一來&#xff0c;每個人都可以建立不與…

java內省機制 + 內省是什么 + 內省實現方式 + 和反射的區別

前些天發現了一個巨牛的人工智能學習網站&#xff0c;通俗易懂&#xff0c;風趣幽默&#xff0c;忍不住分享一下給大家。點擊跳轉到教程。 一、內省是什么、實現方式&#xff1a; 內省&#xff08;Introspector&#xff09;是Java語言對Bean類屬性、事件的一種缺省處理方法。…

百度聯合長虹發布第二款云手機 售價900元以下

摘要&#xff1a;【搜狐IT消息】5月15日消息&#xff0c;百度今天宣布聯合長虹發布第二款智能手機&#xff0c;采用3.5英寸屏幕、300萬像素攝像頭&#xff0c;650MHz主頻處理器&#xff0c;零售價格在700-899元之間&#xff0c;中國聯通將為其提供話費補貼。 【搜狐IT消息】5月…

vmware workstation17環境安裝centos7

打開控制面板&#xff0c;搜索“服務”&#xff0c;啟動vmware authorize service -------解決無法開啟虛擬機問題之無法連接MKS 2.虛擬機硬盤擴展為15G------解決安裝centos7時出現的“檢查存儲配置出錯”問題 3.硬盤分區----/boot 300mb&#xff08;不能小于200mb&#xff0…

博客園中的源代碼格式顯示

昨天寫了一篇文章&#xff0c;但是在寫的時候呢&#xff0c;沒有注意&#xff0c;直接將代碼復制上去了&#xff0c;今天正好有人提醒&#xff0c;看到了格式的混亂&#xff0c;借此記錄整理一下&#xff0c;如何能直接粘貼代碼&#xff0c;而且格式&#xff08;縮進&#xff0…

static的使用

類中的靜態變量在程序運行期間&#xff0c;其內存空間對所有該類的對象實例而言是共享的&#xff0c;為了節省系統內存開銷、共享資源&#xff0c;應該對一些適合使用static的變量聲明為靜態變量。 變量聲明為static的使用場景&#xff1a; &#xff08;1&#xff09;變量所…

Linux內核的裁剪和移植

linux內核的裁剪和移植具體都在這個網址里面。https://blog.csdn.net/xie0812/article/details/10816059https://blog.csdn.net/xie0812/article/details/10821779轉載于:https://blog.51cto.com/13401435/2145947

李開復唱衰互聯網手機:大部分公司會失敗

摘要&#xff1a;互聯網企業和手機制造企業之間巨大的鴻溝也被李開復鮮明地指出來&#xff1a;“兩個產業差別巨大&#xff0c;企業基因不同。”百度此前也坦誠表示&#xff0c;與長虹合作的千元機&#xff0c;主要是針對2000元以下的用戶體驗&#xff0c;不能與四五千元的蘋果…

【POJ】3268 Silver Cow Party

題目鏈接&#xff1a;http://poj.org/problem?id3268 題意 &#xff1a;有N頭奶牛&#xff0c;M條單向路。X奶牛開party&#xff0c;其他奶牛要去它那里。每頭奶牛去完X那里還要返回。去回都是走的最短路。現在問這里面哪頭奶牛走的路最長。 題解&#xff1a;對每個奶牛i與X做…

java.util.ConcurrentModificationException異常分析

前些天發現了一個巨牛的人工智能學習網站&#xff0c;通俗易懂&#xff0c;風趣幽默&#xff0c;忍不住分享一下給大家。點擊跳轉到教程。 Java在操作ArrayList、HashMap、TreeMap等容器類時&#xff0c;遇到了java.util.ConcurrentModificationException異常。以ArrayList為例…

redis基本數據類型之String

redis基本數據類型之String redis一共分為5中基本數據類型&#xff1a;String,Hash,List,Set,ZSet String String類型是包含很多種類型的特殊類型&#xff0c;并且是二進制安全的。比如序列化的對象進行儲存&#xff0c;比如一張圖片進行二進制儲存&#xff0c;比如一個簡單…