日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

每个用户做独立的线程同步

發布時間:2024/1/17 编程问答 23 豆豆
生活随笔 收集整理的這篇文章主要介紹了 每个用户做独立的线程同步 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

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

之前開發一個分享信息的第三方平臺的需求,分享時間是有間隔的,比如說20秒內只能分享一次,

多出的動態里面不顯示,這樣的話如果用戶在20秒內連續多次分享,那么將導致只顯示一次動態,

這時候就必須為每一個用戶的分享操作做獨立的同步,即使有多個分享操作,也是同步執行,執行間隔20秒

思路,為每個用戶創建不同的映射對象,并使用這個對象作為鎖

import java.util.HashMap; import java.util.Map; import java.util.Timer; import java.util.TimerTask;public class UserThread {public static Map<String, Object> map = new HashMap<String, Object>();//存儲靜態的鎖對象//每小時清空map對象static{long perHour = 1000*60*60;Timer perHourTimer = new Timer();perHourTimer.scheduleAtFixedRate(new TimerTask() {public void run() {map.clear();}}, perHour, perHour);}public static void syn(int userId){String key = userId+"";Object obj = map.get(key);if(obj == null){obj = new String(key);map.put(key, obj);}synchronized (obj) {try {Thread.sleep(3000);System.out.println(Thread.currentThread().getName());} catch (Exception e) {}}}/*** 會出現兩種情況:* (1)第一、三、四個線程會在3秒后異步執行,第二個線程由于與第一個線程同步,6秒后才會執行* (2)第二個線程比第一個線程先搶到資源,3秒后執行,第一個線程6秒后執行*/public static void main(String[] args) {Thread t1 = new Thread(){public void run() {UserThread.syn(1);};};t1.setName("線程一");t1.start();Thread t2 = new Thread(){public void run() {UserThread.syn(1);};};t2.setName("線程二");t2.start();Thread t3 = new Thread(){public void run() {UserThread.syn(2);};};t3.setName("線程三");t3.start();Thread t4 = new Thread(){public void run() {UserThread.syn(3);};};t4.setName("線程四");t4.start();}}

為什么還會需要用到map來存儲鎖呢,直接用userId+作為鎖對象豈不是得到如此效果,

為何還要如此的麻煩呢。那么接下來我們就這樣來試試看吧。


public class UserThread {public static void syn(int userId){Object obj = userId+"";synchronized (obj) {try {Thread.sleep(3000);System.out.println(Thread.currentThread().getName());} catch (Exception e) {}}}/*** 四個線程在三秒后同時執行*/public static void main(String[] args) {Thread t1 = new Thread(){public void run() {UserThread.syn(1);};};t1.setName("線程一");t1.start();Thread t2 = new Thread(){public void run() {UserThread.syn(1);};};t2.setName("線程二");t2.start();Thread t3 = new Thread(){public void run() {UserThread.syn(2);};};t3.setName("線程三");t3.start();Thread t4 = new Thread(){public void run() {UserThread.syn(3);};};t4.setName("線程四");t4.start();}} 結果是四個線程在三秒后同時執行,為什么會這樣呢。問題就出在Object

obj = userId+"";這里,下面我們執行一個main方法

public static void main(String[] args) {String str1 = "";String str2 = "";System.out.println(str1 == str2);//結果為true,這是意料之中,大家都知道,字符串有常量池String str3 = str1+str2;System.out.println(str1 == str3);//結果為false,str3也是空字符串,//可見str3不是從常量池取出的,而是組合成新的字符串對象并返回}


因此,線程一與線程二鎖的對象是不一樣的,所有無法實現同步。

總之,線程的同步是建立在鎖對象的基礎上的,誰搶到這個對象,誰就有執行的權限,

執行完后釋放鎖,由后面的線程繼續搶奪。



以上都是針對同一個需要同步的代碼塊的討論,那么不同的代碼塊那同一個對象作為鎖會是什么結果呢


public class UserThread {public static void syn(){Object obj = "";synchronized (obj) {try {Thread.sleep(3000);System.out.println(Thread.currentThread().getName());} catch (Exception e) {}}}public static void syn2(){Object obj = "";synchronized (obj) {try {Thread.sleep(3000);System.out.println(Thread.currentThread().getName());} catch (Exception e) {}}}/*** 二個線程都是同步先后執行*/public static void main(String[] args) {Thread t1 = new Thread(){public void run() {UserThread.syn();};};t1.setName("線程一");t1.start();Thread t2 = new Thread(){public void run() {UserThread.syn2();};};t2.setName("線程二");t2.start();}}

所以,不管做何種同步操作,鎖對象只能被一個線程搶到,不同的代碼塊,如果不是特殊需求,

千萬不要使用相同對象作為鎖,否則會對大大降低程序性能

轉載于:https://my.oschina.net/eatsuger/blog/78147

總結

以上是生活随笔為你收集整理的每个用户做独立的线程同步的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。