[英]Mutual Exclusion using JAVA 2-Threads Solution
I am trying to implement 2-threads solution using LockOne(Mutually Exclusive) Algorithm. 我正在尝试使用LockOne(互斥)算法实现2线程解决方案。 Implementing this algorithm, i am trying work out a thread defining my own lock methods but i am not getting the desired output.
实现此算法,我正在尝试制定一个定义自己的锁定方法的线程,但未获得所需的输出。 When i run the program..all i get as output is "Thread-0 Locked" and "Thread-1 Locked"..Can anyone plz let me know where am i going wrong?
当我运行程序时..我得到的所有输出都是“ Thread-0 Locked”和“ Thread-1 Locked” ..有人可以让我知道我要去哪里吗? my code is given below
我的代码如下
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++;
}
}
}
There are two problems in your code. 您的代码中有两个问题。
if(!locked)
and set locked=true
is not atomic operation, which means two threads can find it not locked and lock it at same time. if(!locked)
并设置locked=true
不是原子操作,这意味着两个线程可以找到未锁定并同时锁定它。 locked
and current
, so one thread may not read the fresh value the other thread set on them because of memory barriar . locked
和current
没有同步,因此一个线程可能由于内存阻塞而无法读取另一个线程设置的新值。 You can solve this with AtomicBoolean
and volatile
: 您可以使用
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);
}
}
And another solution in case if you need reentrant lock with fair acquisition policy: 如果您需要采用公平获取政策的可重入锁定,那么还有另一种解决方案:
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.