Java 整数值未刷新

Java 整数值未刷新,java,multithreading,Java,Multithreading,我试图使用两个单独的线程来打印偶数和奇数,它们通过wait和notify相互通信 我知道我指的是堆中的整数对象。因此,一个线程所做的更改应该对两个线程都可见。我还使用volatile关键字来声明integeti 我似乎无法理解变量I的值是如何显示为1的,即使它已递增。 代码的输出是 Even Thread got lock i=1 Even Thread waiting.. i=1 Odd Thread got lock i=1 Odd Thread : i=2 Odd Thread

我试图使用两个单独的线程来打印偶数和奇数,它们通过wait和notify相互通信

我知道我指的是堆中的整数对象。因此,一个线程所做的更改应该对两个线程都可见。我还使用volatile关键字来声明integeti

我似乎无法理解变量I的值是如何显示为1的,即使它已递增。

代码的输出是

 Even Thread got lock i=1
 Even Thread waiting.. i=1
 Odd Thread got lock i=1
Odd Thread  : i=2
 Odd Thread Run called NotifyAll
 Odd Thread got lock i=2
 Odd Thread waiting.. i=2
 Even Thread woken up.. i=1
 Even Thread waiting.. i=1
打包程序;
公共课偶数{
静态对象lck=新对象();
可变静态整数i=1;
易失性静态整数N=1000;
公共静态void main(字符串参数[]){
EvenRunner e=新的EvenRunner(lck,i,N);
OddRunner o=新OddRunner(lck,i,N);
螺纹t1=新螺纹(e,“偶数螺纹”);
螺纹t2=新螺纹(o,“奇数螺纹”);
t1.start();
t2.start();
试一试{
t1.join();
t2.连接();
}捕获(中断异常例外){
System.out.println(“中断:+ex”);
}
}
}
类EvenRunner实现可运行{
对象lck;
整数i;
整数N;
EvenRunner(对象lck、整数i、整数N){
这个.lck=lck;
这个。i=i;
这个,N=N;
}
@凌驾
公开募捐{
而
预期的输出应该是,其他线程也应该在变量I递增后将其值视为2

在构造
evenRunner
oddRunner
时,将相同的
Integer
引用作为实例字段复制到每个类中

但是
Integer
是不可变的-当您执行
++i;
时,它会更改字段以引用不同的
Integer
对象。它不会修改现有Integer对象的内容…因此您的两个线程在完全不同的字段上操作,并且根本不会交互


如果您想要一个两个线程都可以修改的对象,请改用。

作为旁白,我强烈建议您遵循Java命名约定,类名为
EvenRunner
OddRunner
。谢谢,先生,从下一次开始我会更加小心。因为整数是不可变的,所以无法修改它在其他线程中,引用它也会看到新值?对吗?如果我想要一个可变的共享对象而不是整数对象,我需要创建一个可变的共享对象。@ashish2199是的,这就是“不可变”的意思。另外,使用原语也没有帮助,因为它们是每个线程的本地对象,而其他线程不知道什么是i在其他线程中的值,因此两者之间没有同步。对吗?@ashish2199:这并不是说它是线程的本地值,而是每个对象都有一个单独的字段。即使只涉及一个线程,您也会在这里看到相同的行为。
package programs;


public class EvenOdd {
    static Object lck = new Object();
    volatile static Integer i=1;
    volatile static Integer N = 1000;
    public static void main(String args[]){
        EvenRunner e = new EvenRunner(lck, i, N);
        OddRunner o = new OddRunner(lck, i, N);
        Thread t1 = new Thread(e,"Even Thread ");
        Thread t2 = new Thread(o,"Odd Thread ");

        t1.start();
        t2.start();

        try {
            t1.join();
            t2.join();
        }catch(InterruptedException ex) {
            System.out.println("Interrupted : "+ex);
        }

    }
}
class EvenRunner implements Runnable{
    Object lck;
    Integer i;
    Integer N;
    EvenRunner(Object lck,Integer i,Integer N){
        this.lck=lck;
        this.i=i;
        this.N=N;
    }
    @Override
    public void run() {


        while(i<N) {

            synchronized(lck) {
                System.out.println(" Even Thread got lock i="+i);
                while(i%2==1){
                    try {
                        System.out.println(" Even Thread waiting.. i="+i);
                        lck.wait();
                        System.out.println(" Even Thread woken up.. i="+i);
                    }catch(InterruptedException e) {
                        System.out.println("Interrupted thread : "+e);
                    }
                }

                ++i;
                System.out.println(Thread.currentThread().getName()+" : i="+i);

                System.out.println(" Even Thread Run called NotifyAll");
                lck.notifyAll();
            }
        }
    }
}
class OddRunner implements Runnable{
    Object lck;
    Integer i;
    Integer N;
    OddRunner(Object lck,Integer i,Integer N){
        this.lck=lck;
        this.i=i;
        this.N=N;
    }
    @Override
    public void run() {
        while(i<N) {
            synchronized(lck) {
                System.out.println(" Odd Thread got lock i="+i);
                while(i%2==0){
                    try {
                        System.out.println(" Odd Thread waiting.. i="+i);
                        lck.wait();
                        System.out.println(" Odd Thread woken up.. i="+i);

                    }catch(InterruptedException e) {
                        System.out.println("Interrupted thread : "+e);
                    }
                }

                ++i;
                System.out.println(Thread.currentThread().getName()+" : i="+i);

                System.out.println(" Odd Thread Run called NotifyAll");
                lck.notifyAll();
            }
        }
    }
}