是否可以锁定显示器的不同区域?
Posted
技术标签:
【中文标题】是否可以锁定显示器的不同区域?【英文标题】:Is it possible to lock different areas of a monitor? 【发布时间】:2021-06-21 02:44:44 【问题描述】:我正在使用多线程,这是我的场景。
多个线程正在运行 线程必须访问监视器中的不同方法 这些方法不会相互冲突,也不会触及相同的资源 我可以锁定监视器中的不同方法/区域吗?下面的代码只是我正在尝试做的一个示例,但我希望它能够传达我的主要问题。 我有多个线程在运行,并且在监视器中有两个 ArrayList(虽然不在下面的示例代码中)。这两种方法适用于两种不同的 ArrayList,但一种方法不会触及另一种,反之亦然。如果我这样做,我会失去并行性吗?
这是监控代码:
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
public class Monitor
Lock lock1 = new ReentrantLock();
Lock lock2 = new ReentrantLock();
public void loopLiten(Integer ID, String type)
try
lock1.lock();
System.out.println(Thread.currentThread().getName() + " does a small loop.");
for(Integer i = 0; i < 1000000000; i++)
catch(Exception e)
System.out.println("Error.");
finally
System.out.println(Thread.currentThread().getName() + " is done making a " + type + " loop.");
lock1.unlock();
public void loopStor(Integer ID, String type)
try
lock2.lock();
System.out.println(Thread.currentThread().getName() + " does a bigger loop.");
for(Integer i = 0; i < 1000000000; i++)
catch(Exception e)
System.out.println("Error.");
finally
System.out.println(Thread.currentThread().getName() + " is done making a " + type + " loop.");
lock2.unlock();
【问题讨论】:
【参考方案1】:正如 cmets 中已经讨论的那样,您的代码已经在使用显式锁,并且这样做很好。只要使用 2 把锁的代码不对相同的数据进行操作,就不会有任何问题。
但是,请注意,对相同数据的访问可能会发生在“道路”的更远处,即取决于您在循环中所做的事情,您仍然可以获得赛车条件等。 想象一下,您的单独数组列表包含相同的实例,并且两种方法都在访问这些实例 - 这可能会导致并发问题。
最后,关于 Java 中的“监视器”的注释:监视器对象与 synchronized
结合使用,即您不会在这些对象上获得显式锁定。相反,每当您输入同步块时,运行时都会尝试在幕后锁定关联的监视器。 synchronized
块基本上有 2 种口味:
synchronized void runLocked()
这样的方法,其中封闭的实例或类(对于静态方法)是关联的监视器对象
可以在不同的监视器对象上操作但需要显式设置的同步块,例如synchronized(this) ...
或 synchronized(someObject)
。
要完全同步某个对象的方法,您需要创建这些同步方法,但如果您需要在对象的某些部分上同步,您需要使用具有不同监视器对象的同步块(可以只是 Object
的实例)或者像你一样明确地使用锁。
【讨论】:
【参考方案2】:线程必须访问监视器中的不同方法
监视器只是一个用于ensure mutual exclusion 访问给定资源/代码块的对象。
这些方法不会相互冲突,也不会接触到相同的 资源 我可以锁定监视器中的不同方法/区域吗?
问题实际上应该是“我可以使用不同的锁来锁定那些单独的资源吗”。
您可以为要确保互斥的每个资源创建一个锁。如果这些方法适用于不同的资源,那么您可以使用更细粒度的锁定方法(即锁定 per 单个资源),这自然取决于代码。
我有多个线程正在运行,并且监视器中有两个 ArrayList(不是 虽然在下面的示例代码中)。这两种方法适用于两者 不同的 ArrayLists,但一种方法不会触及另一种方法,并且 反之亦然。
如果这些列表在线程之间共享并同时更新,那么您应该通过(例如)使用显式锁 per 资源来确保线程安全。
如果我这样做会失去并行性吗?
不,实际上你会得到一些。添加锁定机制自然会减少可以并行完成的计算量。但是,通过创建单独的锁 per 列表,您可以确保在不同列表上工作的 2 个线程可以并行工作。如果两个列表都只有一个锁,那么 2 个线程不能同时在这两个单独的列表上工作。
【讨论】:
以上是关于是否可以锁定显示器的不同区域?的主要内容,如果未能解决你的问题,请参考以下文章