[英]Mutual Exclusion using JAVA 2-Threads Solution
我正在嘗試使用LockOne(互斥)算法實現2線程解決方案。 實現此算法,我正在嘗試制定一個定義自己的鎖定方法的線程,但未獲得所需的輸出。 當我運行程序時..我得到的所有輸出都是“ Thread-0 Locked”和“ Thread-1 Locked” ..有人可以讓我知道我要去哪里嗎? 我的代碼如下
public class Main {
static MyLock lock=null;
static int count=0;
public static void main(String[] args) throws InterruptedException {
Thread[] threads=new Thread[2];
threads[0]=new Thread(new MyThread());
threads[1]=new Thread(new MyThread());
lock=new MyLock();
threads[0].start();
threads[1].start();
threads[0].join();
threads[1].join();
System.out.println(count);
}
}
public class MyLock{
private boolean locked=false;
private String current;
public void lock() {
if(!locked){
locked=true;
current=Thread.currentThread().getName();
}
System.out.println(Thread.currentThread().getName()+" locked");
while(locked && current!=Thread.currentThread().getName());
}
public void unlock() {
System.out.println(Thread.currentThread().getName()+" unlocked");
locked=false;
}
}
public class MyThread implements Runnable{
@Override
public void run() {
int i=1;
while(i<=100){
Main.lock.lock();
Main.count++;
Main.lock.unlock();
i++;
}
}
}
您的代碼中有兩個問題。
if(!locked)
並設置locked=true
不是原子操作,這意味着兩個線程可以找到未鎖定並同時鎖定它。 locked
和current
沒有同步,因此一個線程可能由於內存阻塞而無法讀取另一個線程設置的新值。 您可以使用AtomicBoolean
和volatile
解決此問題:
import java.util.concurrent.atomic.AtomicBoolean;
public class MyLock{
private AtomicBoolean locked = new AtomicBoolean(false);
private volatile String current;
public void lock() {
for (;;) {
if(!locked.get()){
if (locked.compareAndSet(false, true)) {
current = Thread.currentThread().getName();
System.out.println(current + " locked");
return;
}
}
}
}
public void unlock() {
System.out.println(current + " unlocked");
locked.set(false);
}
}
如果您需要采用公平獲取政策的可重入鎖定,那么還有另一種解決方案:
public class MyLock
{
private String holder;
private Queue<Long> next = new ConcurrentLinkedQueue<>();
private Object syncLock = new Object();
public void lock()
{
Long threadId = Thread.currentThread().getId();
this.next.add(threadId);
boolean acquired = false;
while (!acquired)
{
synchronized (this.syncLock)
{
if (this.holder == null)
{
if (this.next.peek() == threadId)
{
this.holder = Thread.currentThread().getName();
System.out.println(this.holder + " locked");
acquired = true;
}
}
else
{
if (this.holder.equals(Thread.currentThread().getName()))
{
acquired = true;
}
}
}
}
this.next.remove(threadId);
}
public void unlock()
{
synchronized (this.syncLock)
{
System.out.println(Thread.currentThread().getName() + " unlocked");
this.holder = null;
}
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.