我在ReentrantLock类中对方法进行了java描述。我的意图是看看等待获得锁的线程是否被打断,可能是我做错了。我知道有一种显式的方式来调用线程上的中断,而且我正在使用的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()));
}
}
现在看下面的控制台输出:当每个线程获得并释放锁时,控制台日志显示相对顺序。
我的问题是:1)为什么会出现这种交织行为?为什么超过一个线程能够获得锁(至少根据控制台输出),这几乎就像获取锁的递归行为。还是仅仅因为控制台输出与实际发生的事情不同步? 2)是否与执行程序处理耗时线程的方式有关,并且是正常的行为?
发布于 2017-10-30 00:41:49
谢谢你的评论!我读到了新的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()));
}
}
并发现所有这些线程都在忙着等待。现在,使用新的方法,我观察到,所有未能获得锁的线程都继续前进,从来不关心在那里返回.Are --任何能够同时满足线程池最佳使用和能够通知下一个最有价值的候选线程的设计模式。
https://stackoverflow.com/questions/47004378
复制相似问题