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

每个用户做独立的线程同步相关推荐

  1. 分享Web应用运行的细节问题:预编译提高网站性能、跟踪用户习惯和解决线程同步...

    在这个文章里,我将分享一下在iOpenWorks.com这个网站试运行中碰到的若干问题和解决方案,这些问题包含了:(1)如何通过ASP.NET MVC预编译提高性能:(2)如何知道网站在运行中,用户响 ...

  2. 操作系统用户态内核态线程同步

    1.计算机系统中有两类程序:系统程序和应用程序.为了保证系统程序不被应用程序破坏,为计算机设置了两种状态:内核态和用户态. 内核态运行的程序可以访问计算机的任何资源不受限制. 用户态运行的程序可以直接 ...

  3. 用户模式下的线程同步

    在以下两种基本情况下,线程之间需要相互通信 1.需要让多个线程同时访问一个共享资源,同时不能破坏资源的完整性 2.一个线程需要通知其他线程某项任务已经完成. 原子访问相关的内容就直接略过了,因为感觉实 ...

  4. Windows用户模式下的线程同步

    Interlocked系列函数 原子访问:线程在访问某个资源的时候能保证没有其他线程会在同一时刻访问同一资源 函数名 功能 InterlockedExchangeAdd InterlockedExch ...

  5. C#并行编程(6):线程同步面面观

    理解线程同步 线程的数据访问 在并行(多线程)环境中,不可避免地会存在多个线程同时访问某个数据的情况.多个线程对共享数据的访问有下面3种情形: 多个线程同时读取数据: 单个线程更新数据,此时其他线程读 ...

  6. WINDOWS下线程同步探讨

    本文主要讨论WINDOWS应用层编程的线程同步问题.在实际编程过程中,我们经常会遇到线程同步的问题,例如在编写多线程共同访问一个共享资源的程序时,如果多个线程只是读取资源那么就不会涉及到下面我们要讨论 ...

  7. 基本线程同步(三)在同步的类里安排独立属性

    声明:本文是< Java 7 Concurrency Cookbook >的第二章,作者: Javier Fernández González     译者:许巧辉  校对:方腾飞 在同步 ...

  8. (二)线程同步_3---在类中使用相互独立的属性同步

    2019独角兽企业重金招聘Python工程师标准>>> 在类中使用相互独立的属性同步 当使用synchronized关键字去同步一个代码块时,我们必须传递一个引用,通常情况下可以使用 ...

  9. java线程 同步与异步 线程池

    1)多线程并发时,多个线程同时请求同一个资源,必然导致此资源的数据不安全,A线程修改了B线 程的处理的数据,而B线程又修改了A线程处理的数理.显然这是由于全局资源造成的,有时为了解 决此问题,优先考虑 ...

最新文章

  1. 经典SQL(sqlServer)
  2. 由于目标机器积极拒绝,无法联接。microsoft sql server,错误:10061
  3. springmvc+mybatis整合
  4. ELK/EFK — Overview
  5. linux配置adb环境变量配置,Ubuntu下adb环境配置
  6. 记录自定义的代码片段位置
  7. 吉林省统考计算机英语作文,2019年吉林省学位英语作文必背范文(我最……的题材) - 希赛网...
  8. 使用面向对象(OO)的思想,实现循环输入多个会员的信息,根据会员编号,查找会员积分
  9. Qt学习笔记-Qt Graphic View Framework
  10. C++基础::typeid、type_info
  11. 在Ubuntu上为Android系统内置C可执行程序测试Linux内核驱动程序
  12. 联想Lenovo Legion Y9000X 2020 外接扩展屏不显示画面
  13. 学生学籍管理系统数据流图
  14. python accessiblechildren用法_python类继承用法实例分析
  15. 监控神器普罗米修斯Prometheus安装配置
  16. 前端滑动验证+拼图滑动验证效果
  17. 服务器系统lede,[OpenWrt Wiki] 系统配置
  18. 观周鸿祎先生访谈之后感
  19. 画春天的景色计算机教案,中班美术教案《画春天》
  20. 精选上万个(cc协议)游戏素材,一键下载

热门文章

  1. 微信小程序云开发 mysql_微信小程序云开发学习笔记(一)云数据库
  2. python两个列表合并 从小到大排列_Python对两个有序列表进行合并和排序的例子...
  3. java双等号和equals_JAVA编程基础篇:hashCode的特性和作用
  4. matlab中nsamp,matlab用于数字调制,几个函数的使用问题
  5. java面试题七 char转int
  6. springmvc rest风格化案例
  7. VUE之监听属性 watch
  8. 更新json文件_忽略packagelock.json?
  9. 某大学多站联动获取webshell
  10. centos6.4下安装python3.6以及对应的django1.11