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

我有一组资源,它们是Resource类的实例。系统中有作业在运行时进入。每个作业都需要一组这些资源,并且必须独占使用它继续进行所需的所有资源。也就是说,为了让作业能够启动,它必须获取它需要的所有资源的锁,并在完成后释放它获取的所有这些锁。因此,除非它需要的所有资源的所有锁都可用,否则作业无法开始其处理。


作业需要的资源在运行时之前是未知的。作业需要的资源列表作为Collection ArrayList<Resource>.


这样做的一种方法是,在run()每个作业线程的方法中,我可以同步“这个”作业所需的所有资源的锁。


synchronized (resource1) {

    synchronized (resource2) {

        ...


    }

}

但这是硬编码并且无法完成,因为作业所需的资源仅在运行时才知道。


我能想到的另一种方法是将资源放在集合结构中,这样,当获取该集合的锁时,该集合中所有条目的锁也会被获取,并且其他任何人都无法使用。


有Collections.synchronizedList()。但是,它只锁定List,而不锁定列表中的对象。


如何才能做到这一点?


慕森卡
浏览 151回答 2
2回答

繁花如伊

使用循环怎么样,您在运行时遍历Resources可用列表,然后在每次迭代时获取对象上的锁,这是一个示例,我在Object该类中演示了这一点:public static void main(String[] args) {&nbsp; &nbsp; &nbsp; &nbsp;List<Object> list = new ArrayList<>();&nbsp; &nbsp; &nbsp; &nbsp;list.addAll(Arrays.asList(new Object(), new Object(), new Object()));&nbsp; &nbsp; &nbsp; &nbsp;Runnable run = () -> {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;for(Object o: list) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;synchronized (o) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;System.out.println("Current thread " + Thread.currentThread().getName());&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;System.out.println(o.hashCode());&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;try {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;Thread.sleep(2000);&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;}catch (InterruptedException ie){&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;ie.printStackTrace();&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;}&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;//do something useful&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;}&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;}&nbsp; &nbsp; &nbsp; &nbsp;};&nbsp; &nbsp; &nbsp; &nbsp;new Thread(run, "t1").start();&nbsp; &nbsp; &nbsp; &nbsp;new Thread(run, "t2").start();&nbsp; &nbsp; &nbsp; &nbsp;new Thread(run, "t3").start();&nbsp; &nbsp; &nbsp; &nbsp;new Thread(run, "t4").start();&nbsp;}&nbsp;当一个线程获得了特定对象的锁时,其他线程将等待它,但它们可以自由地从 for-each 循环中获取下一个可用对象的锁。

翻过高山走不出你

您可以为 List 接口编写自己的实现,并在列表中查询资源时锁定资源。https://docs.oracle.com/javase/8/docs/api/java/util/List.html
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Java