是否可以锁定显示器的不同区域?

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 个线程不能同时在这两个单独的列表上工作。

【讨论】:

以上是关于是否可以锁定显示器的不同区域?的主要内容,如果未能解决你的问题,请参考以下文章

突出显示具有不同颜色图像的区域及其周围的区域

我可以使用 maphilight 插件在两个不同的地图上突出显示具有相同类别的区域吗?

如何在Android中限制地图?

重新分配/覆盖热键 (Win + L) 以锁定窗口

css 如何根据显示器屏幕大小自动调整显示区域

当用户放大地图上的某个区域时,显示来自不同功能的特定数据