关于多线程的Java初学者问题

关于多线程的Java初学者问题,java,Java,在多年不使用java之后,我正在温习我的java技能。最近,我读了一章关于多线程的内容,其中提到: “但是,如果您有一个访问静态字段的非静态方法,该怎么办? 或访问非静态字段(使用实例)的静态方法 这些案件很快就会变得一团糟,很有可能 如果你有一个静态方法访问 非静态字段,并同步该方法,则获取类上的锁 但是如果有另一个方法也可以访问非静态字段, 这一次使用的是非静态方法?它可能会在当前系统上同步 请记住,静态同步方法和 非静态同步方法不会相互阻塞,它们可以在 同时。“ 为了学习,我一直在尝试编写

在多年不使用java之后,我正在温习我的java技能。最近,我读了一章关于多线程的内容,其中提到:

“但是,如果您有一个访问静态字段的非静态方法,该怎么办? 或访问非静态字段(使用实例)的静态方法 这些案件很快就会变得一团糟,很有可能 如果你有一个静态方法访问 非静态字段,并同步该方法,则获取类上的锁 但是如果有另一个方法也可以访问非静态字段, 这一次使用的是非静态方法?它可能会在当前系统上同步 请记住,静态同步方法和 非静态同步方法不会相互阻塞,它们可以在 同时。“

为了学习,我一直在尝试编写一个示例,上面的代码片段中引用了一个场景:一个程序,其中一个静态同步方法修改一个与非同步方法同时运行的非静态字段

到目前为止,我没有成功地做到这一点。非常感谢您的帮助。谢谢

下面是我完成的一个代码示例。但是,正如预期的那样,线程不会同时运行,因为它们是同步的。我只是想看看书中提到的一个例子,这样我就知道什么是不能做的

class code147_class1{
    int num1 = 111;
    static int num2 = 222;

}//code147_class1


public class code147 implements Runnable {

    code147_class1 z = new code147_class1();

    public static void main (String args[]){
        System.out.println("Program has started...");
        System.out.println("The value of the instance variable is:"+new code147_class1().num1);
        System.out.println("The value of the static variable is:"+code147_class1.num2);

        code147 cd1 = new code147();

        Thread thread1 = new Thread(cd1);
        Thread thread2 = new Thread(cd1);

        thread1.start();
        thread2.start();


    }//main

    public void run(){
        System.out.println("Thread has started for:"+Thread.currentThread().getId());

        try{
        subtract_instance_var(z);
        Thread.sleep(100);
        code147.static_subtract_instance_var(z);
        }
        catch(Exception ex){

        }
    }//run

    public synchronized void subtract_instance_var(code147_class1 x){
       if(x.num1 ==111){

           try{
               Thread.sleep(100);
           }
           catch(Exception ex){
           }

           x.num1 = x.num1 - 11;
           System.out.println("Value is subtracted at thread:"+Thread.currentThread().getId());

       }//if

       System.out.println("The value of instance variable at the end for thread: "+Thread.currentThread().getId()+"  is "+x.num1);

    }//subtract_instance_var

    public synchronized static void  static_subtract_instance_var(code147_class1 x){
        if (x.num1==111){
            try{
                Thread.sleep(100);
            }
            catch(InterruptedException ex){
            }//catch
            x.num1 = x.num1 -11;
            System.out.println("Value is subtracted at thread:"+Thread.currentThread().getId());
        }//if

        System.out.println("STATIC The value of instance variable at the end for thread: "+Thread.currentThread().getId()+"  is "+x.num1);

    }//stati_subtract_var

}//class

运行代码后,我希望实例变量的值为89。然而,程序的结果是100。

您得到的结果100是正确的。
thread1和thread2将同时运行。由于“subtract_instance_var”方法是同步的,一个线程将使变量为100。然后那根线就睡着了。当锁被释放时,其他线程可以执行“subtract\u instance\u var”。但当“x.num1==111”条件失败时,不会发生任何事情。休眠后,当两个线程都尝试执行“static_subtract_instance_var”方法时,仍然“x.num1==111”条件失败。所以变量值保持为100。

得到的结果100是正确的。
thread1和thread2将同时运行。由于“subtract_instance_var”方法是同步的,一个线程将使变量为100。然后那根线就睡着了。当锁被释放时,其他线程可以执行“subtract\u instance\u var”。但当“x.num1==111”条件失败时,不会发生任何事情。休眠后,当两个线程都尝试执行“static_subtract_instance_var”方法时,仍然“x.num1==111”条件失败。因此变量值保持为100。

示例代码不会同时执行静态减法和实例减法。因此,不涉及线程安全

此外,如果原始值为111,则代码仅减11。所以你的结果是100

这里有一个备用main,它将并发执行substract和static_substract

publicstaticvoidmain(字符串参数[]){
System.out.println(“程序已启动…”);
System.out.println(“实例变量的值为:“+new Code147_class1().num1”);
System.out.println(“静态变量的值为:”+Code147_class1.num2);
Code147 cd1=新Code147();
线程线程1=新线程(()->{
IntStream.range(0,5).forEach(i->{
cd1.减去实例变量(cd1.z);
});
}“实例线程”);
线程线程2=新线程(()->{
IntStream.range(0,5).forEach(i->{
静态减去实例变量(cd1.z);
});
}“静态线程”);
thread1.start();
thread2.start();
}//主要
注意,在这段代码中,两个线程从初始值111减去11,每个减去5次。剩下的应该是1。由于线程的安全性,它不会总是这样

带线程安全问题的完整代码
import java.util.stream.IntStream;
类别代码147_类别1{
int num1=111;
}//代码147\u正常\u类别1
公共类代码147{
Code147_OK_class1 z=新代码147_OK_class1();
公共静态void main(字符串参数[]){
System.out.println(“程序已启动…”);
println(“实例变量的值为:”+newcode147_OK_class1().num1);
Code147 cd1=新Code147();
线程线程1=新线程(()->{
IntStream.range(0,5).forEach(i->{
System.out.println(“\t状态减法11”+(i+1));
cd1.减去实例变量(cd1.z);
});
}“实例线程”);
线程线程2=新线程(()->{
IntStream.range(0,5).forEach(i->{
System.out.println(“\t静态减法11#”+(i+1));
静态减去实例变量(cd1.z);
});
}“静态线程”);
thread1.start();
thread2.start();
}//主要
公共同步空减实例变量(代码147\u OK\u class1 x){
//如果(x.num1==111){
试一试{
睡眠(100);
}捕获(例外情况除外){
}
x、 num1=x.num1-11;
System.out.println(“在线程T处减去值”+线程.currentThread().getId());
//}//if
System.out.println(“线程T结尾处的实例变量值”+thread.currentThread().getId())
+“是”+x.num1);
}//减去实例变量
公共同步静态void static\u subtract\u instance\u var(代码147\u OK\u class1 x){
//如果(x.num1==111){
试一试{
睡眠(100);
}捕获(中断异常例外){
}//抓住
x、 num1=x.num1-11;
System.out.println(“静态值在线程T处减去”+线程.currentThread().getId());
//}//if
System.out.println(“线程T末尾实例变量的静态值”
+Thread.cur
Program has started...
The value of the instance variable is:111
    Instance Substract 11 #1
    Static Substract 11 #1
STATIC Value is subtracted at thread T11
STATIC The value of instance variable at the end for thread T11  is 89
    Static Substract 11 #2
Value is subtracted at thread T10
The value of instance variable at the end for thread T10  is 89
    Instance Substract 11 #2
Value is subtracted at thread T10
STATIC Value is subtracted at thread T11
The value of instance variable at the end for thread T10  is 67
    Instance Substract 11 #3
STATIC The value of instance variable at the end for thread T11  is 67
    Static Substract 11 #3
STATIC Value is subtracted at thread T11
Value is subtracted at thread T10
The value of instance variable at the end for thread T10  is 45
    Instance Substract 11 #4
STATIC The value of instance variable at the end for thread T11  is 45
    Static Substract 11 #4
Value is subtracted at thread T10
STATIC Value is subtracted at thread T11
The value of instance variable at the end for thread T10  is 23
    Instance Substract 11 #5
STATIC The value of instance variable at the end for thread T11  is 23
    Static Substract 11 #5
Value is subtracted at thread T10
The value of instance variable at the end for thread T10  is 12
STATIC Value is subtracted at thread T11
STATIC The value of instance variable at the end for thread T11  is 12
Program has started...
The value of the instance variable is:111
    Instance Substract 11 #1
    Static Substract 11 #1
Value is subtracted at thread T10
The value of instance variable at the end for thread T10  is 100
    Instance Substract 11 #2
STATIC Value is subtracted at thread T11
STATIC The value of instance variable at the end for thread T11  is 89
    Static Substract 11 #2
Value is subtracted at thread T10
The value of instance variable at the end for thread T10  is 78
    Instance Substract 11 #3
STATIC Value is subtracted at thread T11
STATIC The value of instance variable at the end for thread T11  is 67
    Static Substract 11 #3
Value is subtracted at thread T10
The value of instance variable at the end for thread T10  is 56
    Instance Substract 11 #4
STATIC Value is subtracted at thread T11
STATIC The value of instance variable at the end for thread T11  is 45
    Static Substract 11 #4
Value is subtracted at thread T10
The value of instance variable at the end for thread T10  is 34
    Instance Substract 11 #5
STATIC Value is subtracted at thread T11
STATIC The value of instance variable at the end for thread T11  is 23
    Static Substract 11 #5
Value is subtracted at thread T10
The value of instance variable at the end for thread T10  is 12
STATIC Value is subtracted at thread T11
STATIC The value of instance variable at the end for thread T11  is 1
class code148_class1{
    int num1 = 111;

}//code148_class1


public class code148 implements Runnable {

    static code148_class1 z = new code148_class1();

    public static void main (String args[]){
        System.out.println("Program has started...");
        System.out.println("The value of the instance variable is:"+z.num1);

        code148 cd1 = new code148();

        Thread thread1 = new Thread(
        ()->{
            cd1.subtract_instance_var(z);
        }
        );
        Thread thread2 = new Thread(
                ()->{
                    cd1.NONstatic_subtract_instance_var(z);
                }
        );

        thread1.start();
        thread2.start();


    }//main

    public void run(){
        System.out.println("Thread has started for:"+Thread.currentThread().getId());

//        try{
//        subtract_instance_var(z);
//        Thread.sleep(100);
//        code148.static_subtract_instance_var(z);
//        }
//        catch(Exception ex){
//            
//        }
    }//run

    public synchronized void subtract_instance_var(code148_class1 x){
       if(x.num1 ==111){

           try{
               Thread.sleep(100);
           }
           catch(Exception ex){
           }

           x.num1 = x.num1 - 11;
           System.out.println("Value is subtracted at thread:"+Thread.currentThread().getId());

       }//if

       System.out.println("The value of instance variable at the end for thread: "+Thread.currentThread().getId()+"  is "+x.num1);

    }//subtract_instance_var

    public synchronized void  NONstatic_subtract_instance_var(code148_class1 x){
        if (x.num1==111){
            try{
                Thread.sleep(100);
            }
            catch(InterruptedException ex){
            }//catch
            x.num1 = x.num1 -11;
            System.out.println("Value is subtracted at thread:"+Thread.currentThread().getId());
        }//if

        System.out.println("STATIC The value of instance variable at the end for thread: "+Thread.currentThread().getId()+"  is "+x.num1);

    }//stati_subtract_var

}//class