Java 似乎Thread.start()执行通知()
我刚刚在java线程中发现了奇怪的行为。 下面是一个代码示例:Java 似乎Thread.start()执行通知(),java,multithreading,monitor,Java,Multithreading,Monitor,我刚刚在java线程中发现了奇怪的行为。 下面是一个代码示例: class Job extends Thread { private Integer number = 0; public void run() { for (int i = 1; i < 1000000; i++) { number++; } } public Integer getNumber() { return nu
class Job extends Thread {
private Integer number = 0;
public void run() {
for (int i = 1; i < 1000000; i++) {
number++;
}
}
public Integer getNumber() {
return number;
}
}
public class Test {
public static void main(String[] args)
throws InterruptedException {
Job thread = new Job();
thread.start();
synchronized (thread) {
thread.wait();
}
System.out.println(thread.getNumber());
}
}
类作业扩展线程{
私有整数=0;
公开募捐{
对于(int i=1;i<1000000;i++){
数字++;
}
}
公共整数getNumber(){
返回号码;
}
}
公开课考试{
公共静态void main(字符串[]args)
抛出中断异常{
作业线程=新作业();
thread.start();
已同步(线程){
thread.wait();
}
System.out.println(thread.getNumber());
}
}
出乎意料的是,它会打印出999999。
似乎在start()方法逻辑的末尾有notify()调用。
有什么想法吗
似乎在start()方法逻辑的末尾有notify()调用
是的,这是真的。当线程完成时,它会执行一个notify()
,这就是thread.join()
的工作方式。下面是Thread.join()
的Java1.6代码示例:
public final synchronized void join(长毫秒)抛出InterruptedException{
长基=System.currentTimeMillis();
long now=0;
如果(毫秒<0){
抛出新的IllegalArgumentException(“超时值为负”);
}
如果(毫秒==0){
while(isAlive()){
等待(0);
}
}否则{
...
这就是说,这可能依赖于实现,不应该依赖于实现
似乎在start()方法逻辑的末尾有notify()调用
是的,这是正确的。当线程完成时,它会执行一个notify()
,这就是thread.join()
的工作方式。下面是thread.join()的Java1.6代码示例:
public final synchronized void join(长毫秒)抛出InterruptedException{
长基=System.currentTimeMillis();
long now=0;
如果(毫秒<0){
抛出新的IllegalArgumentException(“超时值为负”);
}
如果(毫秒==0){
while(isAlive()){
等待(0);
}
}否则{
...
这就是说,这可能依赖于实现,不应该依赖。为什么不打印9999999
?number
只增加了那么多次。请检查较小的循环范围。因为存在线程。wait()除了其他人所说的之外,您还有一个争用条件,测试运行的线程调用start()然后调用wait(),但是不能保证wait()会在start()之后立即发生。您的测试类的线程可能在start()之后阻塞您的作业线程可以在测试类调用WAITE()之前运行任何时间。如果您想立即等待,则应该考虑从Base.Sun(…)中调用WAITE()。如果您调用NoTIFY(),则没有被忽略。这意味着它被称为Stand()的一部分。它将被丢弃。也就是说,线程无法通知自己。为什么它不打印9999999
?number
只增加了那么多次。请检查它是否有更小的循环范围。因为有线程。wait()除了其他人所说的之外,您还有一个争用条件,测试运行的线程调用start()然后调用wait(),但是不能保证wait()会在start()之后立即发生。您的测试类的线程可能在start()之后阻塞您的作业线程可以在测试类调用WAITE()之前运行任何时间。如果您想立即等待,则应该考虑从Base.Sun(…)中调用WAITE()。如果您调用NoTIFY(),则没有被忽略。这意味着它被称为Stand()的一部分。它将被丢弃,即线程无法通知自己。
public final synchronized void join(long millis) throws InterruptedException {
long base = System.currentTimeMillis();
long now = 0;
if (millis < 0) {
throw new IllegalArgumentException("timeout value is negative");
}
if (millis == 0) {
while (isAlive()) {
wait(0);
}
} else {
...