标签: reentrantlock

'fair' 和 'unfair' 锁内部存储的区别

带有类 Reentrant(true) lock 的 Lock 接口的工作方式是它使用BlockingQueue来存储想要获取锁的线程。以这种方式“先来,先出去”的线程-FIFO。都清楚这一点。

但是“不公平锁”到哪里去了,或者 ReentrantLock(false)。他们的内部实现是什么?操作系统如何决定现在选择哪个线程?最重要的是现在这些线程还存储在队列中还是在哪里?(他们一定在某个地方)

java locking reentrantlock

5
推荐指数
1
解决办法
591
查看次数

ReentrantLock同步getter和setter

假设您有以下代码:

public int getSpeedX() {
    speedLock.lock();
    try {
        return speedX;
    } finally {
        speedLock.unlock();
    }
}

public void setSpeedX(int x) {
    speedLock.lock();
    try {
        speedX = x;
    } finally {
        speedLock.unlock();
    }
}
Run Code Online (Sandbox Code Playgroud)

返回速度X好吗?或应该是:

public int getSpeedX() {
    int temp;
    speedLock.lock();
    try {
        temp = speedX;
    } finally {
        speedLock.unlock();
    }
    return temp;
}
Run Code Online (Sandbox Code Playgroud)

哪个是对的?或者他们是等同的?

java concurrency multithreading locking reentrantlock

4
推荐指数
1
解决办法
1068
查看次数

ReentrantLock.lock()不会阻止其他线程

我很难理解ReentrantLock.lock()的行为

我有以下课程

import java.util.concurrent.locks.*;

class BlockingClass {

    private Lock lock = new ReentrantLock();

    private Condition condition = lock.newCondition();

    public void a() {
        lock.lock();
        System.out.println("called in method a(): lock()");

        try {
            System.out.println("called in method a(): await()");
            condition.await();
        } 
        catch (InterruptedException e) {} 
        finally {
            lock.unlock();
            System.out.println("called in method a(): unlock() ");
        }
    }

    public void b() {
        lock.lock();
        System.out.println("called in method b(): lock()");

        System.out.println("called in method b(): signalAll()");
        condition.signalAll();

        lock.unlock();
        System.out.println("called in method b(): unlock() ");
    }
}
Run Code Online (Sandbox Code Playgroud)

我运行以下测试:

class BlockingClassTest …
Run Code Online (Sandbox Code Playgroud)

java concurrency multithreading reentrantlock

4
推荐指数
1
解决办法
2133
查看次数

正确实现乒乓游戏

我被要求执行一个名为"ping"和"pong"的pingpong游戏(意思是ping之前没有乒乓)10次.意思是,控制台中的最终输出应该是:"ping!(1)","pong!(1)","ping!(2)","pong!(2)"等.

需求是使用信号量,reetrantlock和倒计时锁存器实现gamepingpongthread.

我的问题是打印顺序并不总是如我所要求的那样,我想知道我做错了什么.

这是代码:

// Import the necessary Java synchronization and scheduling classes.
import java.util.concurrent.Semaphore;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.locks.ReentrantLock;
import java.util.concurrent.locks.Condition;

/**
 * @class PingPongRight
 *
 * @brief This class implements a Java program that creates two
 *        instances of the PlayPingPongThread and start these thread
 *        instances to correctly alternate printing "Ping" and "Pong",
 *        respectively, on the console display.
 */
public class PingPongRight
{
    /**
     * @class SimpleSemaphore
     *
     * @brief This class provides a simple counting semaphore …
Run Code Online (Sandbox Code Playgroud)

java concurrency semaphore countdownlatch reentrantlock

4
推荐指数
1
解决办法
3938
查看次数

多个条件与多个锁

对于特定的线程安全数据结构,我需要保护对中央数据结构(即字节数组)的访问.在这种情况下,我选择使用ReentrantLocks,因为它的公平性政策以及创建多个条件的高级功能.

并发的条件很复杂,如下所示:

  1. 中心字节数组必须独占保护(即一次一个线程).
  2. 两个访问方法(foo和bar)必须能够并发运行(如果它们尝试访问中心字节数组,则在内部阻塞).
  3. 对任何方法(foo和bar)的调用都需要是独占的(即从不同的线程多次调用foo将导致一个线程阻塞).

在我最初的实现中,我选择实现两个嵌套锁,如下所示:

ReentrantLock lockFoo = new ReentrantLock(true);
ReentrantLock lockCentral = new ReentrantLock(true);

Condition centralCondition = lockCentral.newCondition();

public void foo(){
    // thread-safe processing code here

    lockFoo.lock();        
    lockCentral.lock();

    try{
        // accessing code here

        try{
            // waits upon some condition for access
            while(someCondition){
                centralCondition.await();
            }
        }catch(InterruptedException ex){
            // handling code here
        }

        // more processing
    }finally{
        lockCentral.unlock();
        lockFoo.unlock();
    }
}
Run Code Online (Sandbox Code Playgroud)

结构在方法上是等效的bar,只需用另一个锁对象lockBar.此外,代码减少了我更复杂的多条件等待,并为简单起见信号到单一条件.

使用这个,我不禁感到代码看起来不必要地复杂和模糊不仅因为有两个嵌套的锁,它们共享一个try-finally,更不用说如何在整个过程中lockCentral释放和重新获取多次lockFoo.

相反,我试图重新组织外锁(lockFoolockBar)作为一个条件lockCentral,如下所示:

ReentrantLock lockCentral …
Run Code Online (Sandbox Code Playgroud)

java concurrency multithreading locking reentrantlock

4
推荐指数
1
解决办法
1859
查看次数

如何在以下环境中确保线程安全?

我有一个名为processOutbox的方法.我希望它是线程安全的.当一个线程在它时,我不希望另一个线程调用此方法.我已经按照以下方式实现了它.我做得对吗?我的实施有漏洞吗?如果有,请告知我如何解决它.

this.start();
    outboxLock.lock();
    timer = new Timer();
    try{
    timer.scheduleAtFixedRate(new TimerTask() {
            public void run() {
               processOutbox();
            }
        }, 0, period);
    } finally{
        outboxLock.unlock();
    }
Run Code Online (Sandbox Code Playgroud)

java multithreading locking timer reentrantlock

4
推荐指数
1
解决办法
78
查看次数

Java在不同的线程上锁定和解锁

我有一个主线程和一个工作线程。主线程将任务添加到队列中,工作线程将其用于计算数据。在将对象放入队列之前,我在任务对象内的ReentrantLock对象(在主线程上调用锁。当工作线程完成了从队列中处理任务的工作后,我称解锁(在工作线程上)。问题是我收到一个IllegalMonitorStateException,因为我在不同的线程上调用了锁定和解锁。

我正在寻找可以在不同线程上执行此操作的替代锁定系统。

例:

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();
    } …
Run Code Online (Sandbox Code Playgroud)

java multithreading locking reentrantlock

4
推荐指数
1
解决办法
1903
查看次数

如何等待直到在 Java 中的另一个线程中释放锁?

我想弄清楚我们如何才能正确地等待另一个线程中的锁被释放。

我认为代码会更好地解释我的意思:

myLock.lock();
sendSomewhereMyLock(myLock); //creates new threads inside
myLock.waitUntilReleasedByAnotherThread(60L, TimeUnit.SECONDS);
//do something after the lock is released
Run Code Online (Sandbox Code Playgroud)

我认为这tryLock(long time, TimeUnit unit)是我需要的方法,但 Java 文档说该方法将立即执行,因为当前线程获取了锁:

如果锁可用,则此方法立即返回 true 值。如果锁不可用,则当前线程将出于线程调度目的而被禁用并处于休眠状态,直到发生以下三种情况之一:

  • 锁被当前线程获取;或者
  • 其他一些线程中断当前线程,支持中断获取锁;或者
  • 经过指定的等待时间

那我应该用什么?

java multithreading locking reentrantlock

4
推荐指数
2
解决办法
4457
查看次数

Java 8 可重入锁和条件导致 IllegalMonitorStateException:当前线程不是所有者

我已经在这里搜索过这个错误,但我认为我的代码看起来是正确的:

  1. 我在尝试之外获得了锁..终于
  2. 我在最后部分有一个解锁
  3. 我只是试图等待锁内的情况。
  4. 我什至打印当前锁是否由该线程持有并且返回 true。

这是代码的摘录,如果我尝试运行代码,我会得到 java.lang.IllegalMonitorStateException:当前线程不是所有者。错误出在 cond.wait() 方法中。

public void takeARest() {
    lock.lock();
    try {
        while (disembark < totalPassengers) {
            System.err.printf("Held by %s%n",lock.isHeldByCurrentThread());
            cond.wait();
        }
    } catch (InterruptedException e) {
        e.printStackTrace();
    } finally {
        lock.unlock();
    }
}
Run Code Online (Sandbox Code Playgroud)

有任何想法吗?

java locking reentrantlock

4
推荐指数
1
解决办法
1351
查看次数

如果同一个线程一次又一次地获取锁,那么 ReentrantLock 如何公平?

我对高级 Java 和学习可重入锁相当陌生。我知道 ReentrantLock 有一个公平参数,它确保将锁提供给大多数饥饿的线程(与同步内部锁的情况不同。)

但是,Reentrant 也意味着同一个线程可以通过增加holdCount 一次又一次地重新获取锁。如果同一个线程永远获取锁,如何保证公平性?

java multithreading reentrantlock

3
推荐指数
1
解决办法
322
查看次数