簡體   English   中英

Java鎖定和解鎖不同的線程

[英]Java lock and unlock on different thread

我有一個主線程和一個工作線程。 主線程將任務添加到隊列中,工作線程將它們用於計算數據。 在我將對象放入隊列之前,我在任務對象內部調用ReentrantLock對象( 在主線程上 )。 當工作線程完成處理隊列中的任務時,我調用unlock( 在工作線程上 )。 問題是我得到一個IllegalMonitorStateException,因為我在不同的線程上調用lock和unlock。

我正在尋找一個替代鎖系統,我可以在不同的線程上執行此操作。

例:

public class Worker extends Thread {
    public static Queue<Task> tasks = new ConcurrentLinkedQueue<Task>();

    @Override
    public void run() {
        while (true) {
            Task task = tasks.poll();

            if (task != null) {
                task.work();
                task.lock.unlock(); // Here is the unlock, Task#i should not change up to now
            }
        }
    }
}


public class Task {
    private int i = 0;
    public Lock lock;

    public void setI(int i) {
        lock.lock();
        this.i = i;
        lock.unlock();
    }

    public void work() {
        System.out.println(i);
    }
}


public class Test {
    Task task = new Task();

    public void addTask() {
        task.lock.lock(); // Here is the lock, Task#i should not change
        Worker.tasks.add(task);
    }
}

為什么不使用只有一個許可證的信號量 您可以獲得單一許可證,而不是鎖定操作。 您應該始終使用release()釋放鎖。

根據這個問題,設計多線程應用程序看起來並不正確。

工作線程應該處理對象的創建,或者你應該將不可變對象傳遞給工作線程,一旦工作線程完成,它就可以將結果傳遞回主線程。

我不認為在一個線程中獲取鎖定並在另一個線程中解鎖是有道理的。

您不需要替代鎖定系統。 ConcurrentLinkedQueue數據結構已經提供了自己的鎖系統並保證了線程安全。 不需要額外的鎖定。

但是你在這里重新發明輪子。 我建議你看一下ExecutorServiceThreadPools 雖然自己構建東西是一個很好的學習經歷。 它也是錯誤的重要來源。

ExecutorService workerPool = Executors.newFixedThreadPool(10); // 10 worker threads
...
Runnable myTask = ...;
workerPool.submit(myTask); // called from the main thread
...

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM