为了账号安全,请及时绑定邮箱和手机立即绑定

运行时之前未知的多个对象作为 Java 线程的锁

运行时之前未知的多个对象作为 Java 线程的锁

慕森卡 2022-07-27 21:32:56
我有一组资源,它们是Resource类的实例。系统中有作业在运行时进入。每个作业都需要一组这些资源,并且必须独占使用它继续进行所需的所有资源。也就是说,为了让作业能够启动,它必须获取它需要的所有资源的锁,并在完成后释放它获取的所有这些锁。因此,除非它需要的所有资源的所有锁都可用,否则作业无法开始其处理。作业需要的资源在运行时之前是未知的。作业需要的资源列表作为Collection ArrayList<Resource>.这样做的一种方法是,在run()每个作业线程的方法中,我可以同步“这个”作业所需的所有资源的锁。synchronized (resource1) {    synchronized (resource2) {        ...    }}但这是硬编码并且无法完成,因为作业所需的资源仅在运行时才知道。我能想到的另一种方法是将资源放在集合结构中,这样,当获取该集合的锁时,该集合中所有条目的锁也会被获取,并且其他任何人都无法使用。有Collections.synchronizedList()。但是,它只锁定List,而不锁定列表中的对象。如何才能做到这一点?
查看完整描述

2 回答

?
繁花如伊

TA贡献2012条经验 获得超12个赞

使用循环怎么样,您在运行时遍历Resources可用列表,然后在每次迭代时获取对象上的锁,这是一个示例,我在Object该类中演示了这一点:


public static void main(String[] args) {

       List<Object> list = new ArrayList<>();

       list.addAll(Arrays.asList(new Object(), new Object(), new Object()));

       Runnable run = () -> {

           for(Object o: list) {

               synchronized (o) {

                   System.out.println("Current thread " + Thread.currentThread().getName());

                   System.out.println(o.hashCode());

                   try {

                       Thread.sleep(2000);

                   }catch (InterruptedException ie){

                       ie.printStackTrace();

                   }

                   //do something useful

               }

           }

       };

       new Thread(run, "t1").start();

       new Thread(run, "t2").start();

       new Thread(run, "t3").start();

       new Thread(run, "t4").start();

 } 

当一个线程获得了特定对象的锁时,其他线程将等待它,但它们可以自由地从 for-each 循环中获取下一个可用对象的锁。


查看完整回答
反对 回复 2022-07-27
?
翻过高山走不出你

TA贡献1875条经验 获得超3个赞

您可以为 List 接口编写自己的实现,并在列表中查询资源时锁定资源。

https://docs.oracle.com/javase/8/docs/api/java/util/List.html


查看完整回答
反对 回复 2022-07-27
  • 2 回答
  • 0 关注
  • 150 浏览

添加回答

举报

0/150
提交
取消
微信客服

购课补贴
联系客服咨询优惠详情

帮助反馈 APP下载

慕课网APP
您的移动学习伙伴

公众号

扫描二维码
关注慕课网微信公众号