繁体   English   中英

使用JAVA 2线程解决方案的互斥

[英]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++;
        }
    }

}

您的代码中有两个问题。

  1. if(!locked)并设置locked=true不是原子操作,这意味着两个线程可以找到未锁定并同时锁定它。
  2. 变量lockedcurrent没有同步,因此一个线程可能由于内存阻塞而无法读取另一个线程设置的新值。

您可以使用AtomicBooleanvolatile解决此问题:

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM