我正在 ReentrantLock 类中浏览 lockInterruptibly 方法的java doc说明。 我的目的是看看等待获取锁的线程是否正在被中断,可能是我做错了。我知道有一种在Thread上调用中断的明确方法,而我正在使用的executorService可能已经在它的API下包含了这个概念。
使用锁定方法也可以看到此行为
我的目的是详细了解这个概念
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()));
}
}
现在看下面的控制台输出: console logs showing the relative order, when each thread acquires lock and releases it
我的问题是: 1)为什么这种交错行为? 为什么超过1个线程能够获取锁(至少根据控制台输出),它几乎就像获取锁的递归行为。或者仅仅因为控制台输出与实际发生的事情不同步? 2)它与执行者处理耗时线程的方式有关并且是正常行为吗?
答案 0 :(得分:0)
感谢您的评论!我正在阅读关于新的Lock api以及如何在实际“获取”它之前尝试锁定。所以我想编写线程是否真的不阻塞。 上面的更新代码 为执行者分配5个线程和10个任务。所有未能获得锁定的线程继续打印'for'循环。这意味着当锁定获取线程在“关键部分”工作时,他们“不忙等待”
相比之下,我也实现了同步的方式
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()));
}
}
并发现确实所有这些线程都忙着等待。现在有了这样做的新方法,我观察到所有未能获得锁定的线程都继续前进,从不关心返回。是否有任何设计模式可以回答这两种情况,最佳使用线程池并能够通知下一个最有价值的候选者。