当前位置: 首页 > news >正文

网站上做视频如何盈利免费外链平台

网站上做视频如何盈利,免费外链平台,一般购物网站有哪些模块,网站建设咨询公需求: 操作员能够对自己权限下的用户数据进行数据填充,但是不同操作员之间可能会有重复的用户数据,为了避免操作员覆盖数据或者重复操作数据,应该在操作用户数据时加锁,要求加的这一把锁必须是细粒度的锁,…

需求:

操作员能够对自己权限下的用户数据进行数据填充,但是不同操作员之间可能会有重复的用户数据,为了避免操作员覆盖数据或者重复操作数据,应该在操作用户数据时加锁,要求加的这一把锁必须是细粒度的锁,不能锁住所有用户的操作 ,只锁当前操作用户,锁的名字为用户id,在获取到锁之后执行业务操作,否则阻塞等待, 这个单体服务锁工具如何设计?

思路:

思路:

  • 1、锁工具类:首先创建一个ConcurrentHashMap{k(用户id)
    v(锁实例)},包含获取锁方法,定时任务晚上删除map中键值对的方法(尝试获取锁,如果能够拿到锁就说明锁没有在使用)
  • 2、在定时任务删除某个键值对期间,去尝试获取写锁,如果能够获取到说明所以经不再被使用,直接删除map中的键值对,之后被删除的锁实例失效
  • 3、其他线如果在删除锁实例之前获取到了,在执行业务的前后需要判断一下这把锁是否和当前key下的锁实例是否一致,一样执行业务,否则锁失效,抛异常,事务回滚

代码:

public class LockUtilsTest {public   static final ConcurrentHashMap<String, ReentrantLock> lockMap = new ConcurrentHashMap<>();private static  ScheduledExecutorService scheduledExecutorService;private static volatile boolean scheduledTaskCreated = false;/*** 获取锁实例,如果锁不存在就创建一个新的锁实例,并将这个锁实例返回* @param lockName* @return*/public static final ReentrantLock getLock(String lockName) {return lockMap.computeIfAbsent(lockName, key -> {//创建定时任务createdTask();return  new ReentrantLock();});}/**** 懒加载 创建定时任务*/private static void createdTask(){System.out.println(Thread.currentThread().getName()+":尝试创建定时任务");if (!scheduledTaskCreated) {synchronized (LockUtilsTest.class) {if (!scheduledTaskCreated) {System.out.println(Thread.currentThread().getName()+":成功创建定时任务");scheduledExecutorService = Executors.newSingleThreadScheduledExecutor();scheduledExecutorService.scheduleAtFixedRate(() -> {// 调用当前类的 clearUserLocks 方法new LockUtilsTest().clearUserLocks();}, 3, 3, TimeUnit.SECONDS);scheduledTaskCreated = true;}else{System.out.println(Thread.currentThread().getName()+":尝试创建定时任务发现定时任务已经被创建");}}}else{System.out.println(Thread.currentThread().getName()+":尝试创建定时任务发现定时任务已经被创建");}}/*** 遍历map,尝试获取锁,没获取到说明这个key的锁还在被使用,获取到就直接删除这个键值对,并且其他拥有这个被删除的锁实例的线程获取到锁也不执行业务*/private  void clearUserLocks() {if (StringUtils.isNotEmpty(lockMap) && lockMap.size() >0){System.out.println(Thread.currentThread().getName()+":执行定时任务,删除未使用的锁");ArrayList<String> keys = new ArrayList<>();lockMap.forEach((key, value) -> {ReentrantLock lock = lockMap.get(key);//获取到锁之后直接删除键值对,否则锁在被使用不删除if (lock.tryLock()){try {keys.add(key);lockMap.remove(key);}finally {lock.unlock();lock = null;//取消强引用防止内存泄露}}});System.out.println(Thread.currentThread().getName()+":被删除的锁:"+keys.toString());}}/*** 极端情况下才会考虑这种删除锁时,可以使用分段锁思想,加入一百万个用户,我按照一个用户一把锁,估计会创建一百万把,但是使用分段锁之后,可以让一万个用户公用一把锁,* 这样就会减少锁的数量,还有频繁加锁和释放锁带来的开销,相比与百万数据公用一把锁改成万人用一把锁,性能是有明显提升的,锁的垃圾回收也要处理好,不要出现内存泄露*//**** 判断锁是否有效 :当定时任务删除对应键的锁时,如果有线程已经获得这个键原来的锁实例没抢到锁时,恰好另一个线程在清空键值对后获取这个key的锁实例,这个key在这一瞬间就会存在两个锁实例* 他们可以同时执行业务,彼此并不互斥,所以当获得锁之后,要再次和当前锁是否一致,只要不一致就说明这个锁实例不能再使用了,会存在线程不安全问题* @param lockName*/public static final Boolean checkLock(String lockName,ReentrantLock checkLock){ReentrantLock nowLock = lockMap.get(lockName);/**确保锁存在并且  比较两个对象是否是一个实例*/if (ObjectUtil.isNotEmpty(nowLock) && checkLock == nowLock){return true;}return false;}//使用这个方法如果有数据库操作,要加事务注解回滚数据public static final void checkLockFlag(String lockName,ReentrantLock checkLock){ReentrantLock nowLock = lockMap.get(lockName);/**确保锁存在并且  比较两个对象是否是一个实例*/if (ObjectUtil.isNotEmpty(nowLock) && checkLock == nowLock){}else{throw new RuntimeException("当前锁已失效");}}
}class LockUtilsTestClass{public static void main(String[] args) {//测试定时任务是否是单例懒加载创建   =》 目标 : 成功创建定时任务//taskTest();//测试一百个线程抢锁,锁阻塞是否生效 =》 目标 :执行业务出现一百次  后缀是同一把锁//lockTest();//测试锁被删除后,已经获取锁实例的线程是否生效  =》 目标:老锁返回友好提示 五次  √delLockTest();}/*** 测试定时任务是否是单例懒加载创建* 预期结果:* 尝试创建定时任务  100次* 尝试创建定时任务发现定时任务已经被创建  99次* 成功创建定时任务  1次*/static void   taskTest(){for (int i = 0; i < 100; i++) {new Thread(() ->{ReentrantLock testLock = LockUtilsTest.getLock("test");}).start();}}/**** 测试锁阻塞是否生效 =》 目标 同一个锁执行业务一百次*/static  void lockTest(){for (int i = 0; i < 100; i++) {new Thread(() ->{String lockName = "fe2r32r23f34t34tf34f34fd";ReentrantLock lock = LockUtilsTest.getLock(lockName);lock.lock();try {System.out.println("执行业务"+lock.toString());}finally {lock.unlock();}}).start();}}static   void delLockTest(){for (int i = 0; i < 5; i++) {new Thread(() ->{String lockName = "fe2r32r23f34t34tf34f34fd";ReentrantLock lock = LockUtilsTest.getLock(lockName);try {Thread.sleep(5000);} catch (InterruptedException e) {e.printStackTrace();}lock.lock();try {if (LockUtilsTest.checkLock(lockName,lock)){//执行业务System.out.println("老锁执行业务");}else{//当前线程持有锁失效,返回友好提示System.out.println("老锁返回友好提示");}}catch (Exception e){e.printStackTrace();}finally {lock.unlock();}}).start();}}
}

工具类优缺点:

  • 使用ConcurrentHashMap作为锁的存储容器有以下优点

  • 线程安全:ConcurrentHashMap本身是线程安全的,多个线程可以并发地访问和修改它,而无需额外的同步。

  • 高效性:ConcurrentHashMap在并发场景下通常比synchronizedMap或Hashtable等同步容器有更好的性能。

  • 灵活性:你可以根据键(例如资源的唯一标识)动态地获取和释放锁,这使得代码更加灵活和可维护。

  • 重用锁对象:尽可能地重用现有的锁对象,而不是为每个新的资源或操作都创建一个新的锁,如果你频繁地创建和销毁锁对象,或者维护大量的锁对象(如存储在ConcurrentHashMap中),那么这确实会增加内存消耗。每个ReentrantLock对象都会占用一定的内存空间,而且如果锁的数量非常大,那么存储这些锁的数据结构(如ConcurrentHashMap)也会占用更多的内存,当你动态地获取锁时,JVM会确保线程安全地访问锁对象,这通常涉及一些底层的同步机制,但这些机制通常不会引入大量的额外内存消耗。同样,释放锁也只是改变锁的状态,使其可以被其他线程获取,这同样是一个轻量级的操作。

  • 注意问题

  • 避免无限制地增长:虽然将锁存储在ConcurrentHashMap中可以限制锁对象的数量,但如果你的应用程序允许无限制地添加新的键(即资源),那么lockMap本身可能会无限制地增长,从而消耗大量内存。确保你的应用程序有适当的机制来管理资源,避免无限制地添加新的锁。

http://www.zhongyajixie.com/news/29761.html

相关文章:

  • 寿光营销型网站建设google全球推广
  • 辽宁建设工程信息网查询系统百度推广优化怎么做的
  • 网站加入悬浮客服外贸网站推广优化
  • 网站开发案例详解下载网站优化有哪些技巧
  • 慈溪 网站建设长尾关键词挖掘词
  • 公司网站建设设计方案百度竞价广告的位置
  • 建站平台隐藏技术支持sem优化师是什么意思
  • 商务网站建设难不难如何注册网站
  • 培训型网站建设方案汕头网站关键词推广
  • 如何建设一个人工智能网站seo排名点击
  • 网站管理系统后台不能发布文章了中国搜索引擎有哪些
  • 开州网站建设汕头seo收费
  • wordpress step2 空白赣州seo外包
  • 在线做名片做海报网站潍坊做网站公司
  • 怎么做网站免费的刷赞数据分析培训课程
  • 嵌入式培训机构排名长沙网站seo优化公司
  • 全能网站建设完全自学手册设计模板网站
  • wordpress 视频 去广告北京seo
  • 注册网站邮箱发送的验证网页无法打开seo查询 站长之家
  • 网站 站外链接seo教程seo官网优化详细方法
  • vs做网站不用建项目北大青鸟培训机构靠谱吗
  • 阿里云1m 宽带做网站服务器网络营销的十种方法
  • 上海网站建设免费推百度seo通科
  • 现在做一个什么的网站比较好怎么制作网页设计
  • 如何将百度云做成网站文件服务器网站制作企业
  • 做网站 徐州如何开发一个网站
  • 搭建网站平台有前途吗seo管理与优化期末试题
  • 网站安全证书过期怎么办产品推广渠道有哪些
  • 网站建设管理 自查 报告山西疫情最新情况
  • 优客逸家网站源码seo搜索引擎优化的内容