为了我自己的理解,我写了两个线程,每个线程输出一行。然而,我想让这两个线程,使他们打印一个接一个。比如说 t1
以及 t2
. 如果 t1
打印自己的消息,然后它必须等待其他线程打印自己的消息。现在我设法通过实验使它工作,但有一些事情我不明白。
这是我的密码:
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;
import java.util.concurrent.FutureTask;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
public class Multithread {
public static void main(String [] m) throws InterruptedException, ExecutionException {
Lock lock = new ReentrantLock();
Condition c1 = lock.newCondition();
Runnable t1 = new Runnable() {
@Override
public void run() {
for(int i : new int[] {1,2,3,4,5}) {
lock.lock();
try {
c1.signal();
System.out.println("In thread 1 - " + i);
try {
c1.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
} finally {
c1.signal();
lock.unlock();
}
}
}
};
Callable<String> t2 = new Callable<String>() {
@Override
public String call() throws Exception {
for(int i : new int[] {1,2,3,4,5}) {
lock.lock();
try {
c1.signal();
System.out.println("In callable 2 - " + i);
try {
c1.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
} finally {
c1.signal();
lock.unlock();
}
}
return "This is callable";
}
};
new Thread(t1, "t1").start();
FutureTask<String> task = new FutureTask<>(t2);
new Thread(task, "t2").start();
//c1.signalAll();
System.out.println(task.get());
}
}
请忽略使用可调用和可运行的代码,而不是使用一种类型。所以这是我对这个准则的解释:
假设t1先抓住锁,这意味着t2正在等待锁被释放
t1级 signal()
然后它打印它的消息,然后在 c1.await()
有了这个逻辑,t2永远不应该打印它的消息,因为t1正在等待,而没有 unlock()
预计起飞时间
但令我惊讶的是,它按我所希望的方式工作,每个线程轮流打印其消息,即:
t1级
t2级
t1级
t2级
等等
我不明白的另一件事是 InterruptedException
从来没有发生过 printStackTrace()
从未达到!
有人能解释一下这里发生了什么事吗?
1条答案
按热度按时间4ioopgfo1#
使用这个逻辑,t2永远不应该打印它的消息,因为t1正在等待并且没有解锁
我想你缺少的是
condition.await()
解锁lock
从哪来的condition
,然后它保证重新锁定lock
在它回来之前。