线程陷入无限等待状态。

huangapple go评论68阅读模式
英文:

Thread is going in infinite wait state

问题

给定一个整数 N,任务是编写一个Java程序,使用两个线程按升序打印前 N 个自然数。然而,输出仅显示数字 1,因为线程进入了无限循环,用户无法调试。

public class OddEven {
    static int totalNos;
    static int counter = 1;
    static Runnable odd = new Runnable() {
        @Override
        public void run() {
            synchronized (this) {
                while(counter < totalNos) {	
                    while (counter%2==0) {
                        try {
                            wait();
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
                    System.out.print(counter + " ");
                    counter++;
                    notify();
                }
            }
        }
    };
    
    static Runnable even = new Runnable() {
        @Override
        public void run() {
            synchronized (this) {
                while(counter < totalNos) {
                    while (counter%2==1) {
                        try {
                            wait();
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
                    System.out.print(counter + " ");
                    counter++;
                    notify();
                }
            }
        }
    };
    
    public static void main(String[] args) {
        System.out.println("输入总数");
        Scanner scObj = new Scanner(System.in);
        totalNos = scObj.nextInt();
        scObj.close();
        Thread oddT1 = new Thread(odd);
        Thread evenT1 = new Thread(even);
        oddT1.start();
        evenT1.start();	 
      
    }
}

注意:我已经翻译了代码部分,不包括注释。

英文:

Given an integer N, the task is to write a Java program to print the first N natural numbers in increasing order using two threads. However, the output is only showing the number 1 as the thread is going into an infinite loop and this is something the user could not debug.

public class OddEven {
    static int totalNos;
    static int counter = 1;
    static Runnable odd = new Runnable() {
        @Override
        public void run() {
            synchronized (this) {
                while(counter &lt; totalNos) {	
                    while (counter%2==0) {
                        try {
                            wait();
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
                    System.out.print(counter + &quot; &quot;);
                    counter++;
                    notify();
                }
            }
        }
    };
    
    static Runnable even = new Runnable() {
        @Override
        public void run() {
            synchronized (this) {
                while(counter &lt; totalNos) {
                    while (counter%2==1) {
                        try {
                            wait();
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
                    System.out.print(counter + &quot; &quot;);
                    counter++;
                    notify();
                }
            }
        }
    };
    
    public static void main(String[] args) {
        System.out.println(&quot;Enter the total no&#39;s&quot;);
        Scanner scObj = new Scanner(System.in);
        totalNos = scObj.nextInt();
        scObj.close();
        Thread oddT1 = new Thread(odd);
        Thread evenT1 = new Thread(even);
        oddT1.start();
        evenT1.start();	 
      
    }
}

答案1

得分: 1

你的两个对象之间没有同步。你的两个对象,evenodd,各自在自己上面同步,等待自己上的条件,以及通知自己。更准确地说,如果它们曾经达到那一点的话,它们本应通知自己,但它们永远不会到达那一点,因为另一个线程从不通知它们。

你需要让两个线程都使用相同的对象进行同步。例如:

public class OddEven {
static final Object lock = new Object();
static int totalNos;
static int counter = 1;
static Runnable odd = new Runnable() {
@Override
public void run() {
synchronized (lock) {
...
lock.wait();
...
lock.notify();
}
}
}
.
.
.
}
英文:

You have no synchronization between the two objects. Each of your two objects, even and odd synchronizes on its own self, waits on its own self, and notifies its own self. Or, more accurately, it would notify its own self if it ever got to that point, but it doesn't get there because the other thread never notifies it.

You need to have both threads use the same object for synchronization. E.g.;

public class OddEven {
static final Object lock = new Object();
static int totalNos;
static int counter = 1;
static Runnable odd = new Runnable() {
@Override
public void run() {
synchronized (lock) {
...
lock.wait();
...
lock.notify();
}
}
}
.
.
.
}

huangapple
  • 本文由 发表于 2023年6月16日 10:38:14
  • 转载请务必保留本文链接:https://go.coder-hub.com/76486638.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定