[英]How thread lock should be handled to keep other threads waiting until downloading a file and then allow all threads to read the file in one go
[英]How to lock a sequence of methods, such that other thread call those same method should be waiting?
假設有一個 Thread 並且它有一系列要執行的方法:
public void task(){
method();
method();
method();
method();
}
我想鎖定整個序列。 也就是說,當該task()
正在執行時,我不希望其他線程執行相同的method()
而是等到整個task()
完成。 需要什么樣的鎖?
您可以使該任務同步:
public synchronized void task() {
method();
method();
method();
method();
}
這將防止其他線程在同一個 object 上調用相同的task()
方法,包括該 object 上的其他synchronized
方法。您可以使用顯式synchronized
語句進行更多控制,例如
public void task() {
synchronized (this) { // or another object
method();
method();
method();
method();
}
}
或者使用你自己的Lock實例:
private final ReentrantLock lock = new ReentrantLock();
public void task() {
lock.lock(); // block until lock is released
try {
method();
method();
method();
method();
} finally {
lock.unlock();
}
}
如果您不想讓所有method()
調用同時運行,只需將相同的機制應用於method()
聲明:
public synchronized void method() // or one of the other two options
如果將這三種機制中的一種應用於task
和method
,您將確保調用task()
的線程將按順序完成所有method()
調用,並防止其他線程同時調用任何method()
。 synchronized
和ReentrantLock
都允許同一個線程多次獲得同一個鎖/監視器(嵌套鎖)。
最后,如果你想允許對method()
的多個並行調用,但只是在執行task()
時不允許,你需要一個共享鎖或讀寫鎖(請參閱ReentrantReadWriteLock )。
這可能是一種選擇,但可能不是最好的。 您可以通過這種方式修改method()
的簽名:
public void method(int serialExecutionCount) {
synchronized(this) {
for (int i = 0; i < serialExecutionCount; i++) {
// body of your method()
}
}
}
現在,您的task()
方法將如下所示:
public void task() {
method(4);
}
現在,如果你像這樣從其他線程調用它:
method(1);
它將等待前 4 個方法調用從task()
方法的調用線程完成。
您需要擁有某種共享鎖,並將其引用傳遞給需要執行該序列的所有線程。
例如,創建一個public static final ReentrantLock LOCK = new ReentrantLock();
在具有 task() 方法的 class 上,在方法 task() 的開頭寫入LOCK.lock();
和LOCK.unlock();
在最后。 現在,所有通過 task() 方法的線程都將嘗試獲取鎖,如果已經被占用,它將阻塞它們。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.