首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >重入锁,忙着等待,由新的tryLock方法解决

重入锁,忙着等待,由新的tryLock方法解决
EN

Stack Overflow用户
提问于 2017-10-29 19:31:51
回答 1查看 418关注 0票数 0

我在ReentrantLock类中对方法进行了java描述。我的意图是看看等待获得锁的线程是否被打断,可能是我做错了。我知道有一种显式的方式来调用线程上的中断,而且我正在使用的executorService可能已经将这个概念封装在了它的API之下。

这种行为也可以用锁方法来观察。

我的目的是详细学习这个概念。

代码语言:javascript
运行
复制
import java.util.Date;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.locks.Lock;

public class LockInterruptibly extends Thread {

    static ExecutorService es = Executors.newFixedThreadPool(5);
    static Lock lock1 = new java.util.concurrent.locks.ReentrantLock();

    public void methodA() {
        if (lock1.tryLock()) {

            try {
                lock1.lockInterruptibly();
                System.out.println("lock acquired by " + this.getName() + "  of method A");
                Thread.sleep(5000);

            } catch (InterruptedException e) {

                System.out.println("this thread " + this.getName() + " was interrupted");
                e.printStackTrace();
            }
        } else {
            System.out.println(this.getName() + "failed to acquire lock");
        }
    }

    public void methodB() {
        for (int i = 0; i < 5; i++) {
            System.out.println("Printed by " + this.getName() + " - " + i);
        }
        lock1.unlock();
        System.out.println(this.getName() + " is exiting at time " + new Date(System.currentTimeMillis()));
    }

    @Override
    public void run() {
        methodA();
        methodB();
    }

    public static void main(String args[]) {
        System.out.println(new Date(System.currentTimeMillis()));
        for (int i = 0; i < 10; i++) {
            Runnable r = new Thread(new LockInterruptibly());
            es.submit(r);
        }
        System.out.println(new Date(System.currentTimeMillis()));
    }
}

现在看下面的控制台输出:当每个线程获得并释放锁时,控制台日志显示相对顺序。

我的问题是:1)为什么会出现这种交织行为?为什么超过一个线程能够获得锁(至少根据控制台输出),这几乎就像获取锁的递归行为。还是仅仅因为控制台输出与实际发生的事情不同步? 2)是否与执行程序处理耗时线程的方式有关,并且是正常的行为?

EN

回答 1

Stack Overflow用户

发布于 2017-10-30 00:41:49

谢谢你的评论!我读到了新的Lock api,以及在实际“获取”它之前如何尝试锁定。所以我想对线程是否真的是非阻塞的进行编码。上面的更新的代码分配给执行器5个线程和10个任务。所有无法获得锁的线程都继续打印“for”循环。这意味着当锁获取线程在“关键部分”工作时,它们“不忙着等待”。

相反,我还实现了同步的方法。

代码语言:javascript
运行
复制
import java.util.ArrayList;
import java.util.Date;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class Synchronized extends Thread {

    static ExecutorService es = Executors.newFixedThreadPool(5);
    static ArrayList<Object> toBeLocked = new ArrayList<Object>();

    public void methodA() {

        synchronized (toBeLocked) {
            try {
                System.out.println("lock acquired by " + this.getName() + "  of method A");
                Thread.sleep(5000);
            } catch (InterruptedException e) {
                System.out.println("this thread " + this.getName() + "was interrupted");
            }
        }

        for (int i = 0; i < 5; i++) {
            System.out.println("Printed by " + this.getName() + " - " + i);
        }
        System.out.println(this.getName() + " is exiting at time " + new Date(System.currentTimeMillis()));
    }

    @Override
    public void run() {
        methodA();
    }

    public static void main(String args[]) {
        System.out.println(new Date(System.currentTimeMillis()));
        for (int i = 0; i < 10; i++) {
            Runnable r = new Thread(new Synchronized());
            es.submit(r);
        }
        System.out.println(new Date(System.currentTimeMillis()));
    }

}

并发现所有这些线程都在忙着等待。现在,使用新的方法,我观察到,所有未能获得锁的线程都继续前进,从来不关心在那里返回.Are --任何能够同时满足线程池最佳使用和能够通知下一个最有价值的候选线程的设计模式。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/47004378

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档