美文网首页
对Java线程安全与不安全的理解

对Java线程安全与不安全的理解

作者: kindol | 来源:发表于2018-07-30 23:57 被阅读0次

    一个线程不安全的类

    public class Count {  
        private int num;  
        public void count() {  
            for(int i = 1; i <= 10; i++) {  
                num += i;  
            }  
            System.out.println(Thread.currentThread().getName() + "-" + num);  
        }  
    }  
    

    正常的理解,调用count()应该会输出55

    在主函数中启动10个线程:

    public class ThreadTest {  
        public static void main(String[] args) {  
            Runnable runnable = new Runnable() {  
                Count count = new Count();  
                public void run() {  
                    count.count();  
                }  
            };  
    
            for(int i = 0; i < 10; i++) {  
                new Thread(runnable).start();  
            }  
        }  
    }  
    

    输出结果如下:

    Thread-0-55  
    Thread-1-110  
    Thread-2-165  
    Thread-4-220  
    Thread-5-275  
    Thread-6-330  
    Thread-3-385  
    Thread-7-440  
    Thread-8-495  
    Thread-9-550
    

    只有Thread-0线程输出的结果是我们期望的,其他的跟想象中的不符,为何?

    每个线程都有自己的工作内存(线程栈),工作内存存储了主内存count对象的一个副本,当线程操作count对象时,首先从主内存复制count对象到工作内存中,然后执行代码count.count(),改变了num值,最后用工作内存中的count刷新主内存的 count

    可以看出,多个线程对同一个实例类的同一个变量操作是不安全的,不安全体现在这个成员变量可能发生非原子性的操作,然而,变量定义在方法内(局部变量)、多个线程访问同一个对象中的同步方法是安全的

    java线程的两个特性:可见性(也就是工作内存会刷新主内存)、有序性(结果取决于线程调度的精准时序)

    相关文章

      网友评论

          本文标题:对Java线程安全与不安全的理解

          本文链接:https://www.haomeiwen.com/subject/ucaqvftx.html