zoukankan      html  css  js  c++  java
  • 【转】Java 多线程(四) 多线程访问成员变量与局部变量

    原文网址:http://www.cnblogs.com/mengdd/archive/2013/02/16/2913659.html

    先看一个程序例子:

      

    复制代码
    public class HelloThreadTest
    {
        public static void main(String[] args)
        {
            HelloThread r = new HelloThread();
    
            Thread t1 = new Thread(r);
            Thread t2 = new Thread(r);
    
            t1.start();
            t2.start();
    
        }
    
    }
    
    class HelloThread implements Runnable
    {
        int i;
    
        @Override
        public void run()
        {
    
            while (true)
            {
                System.out.println("Hello number: " + i++);
    
                try
                {
                    Thread.sleep((long) Math.random() * 1000);
                }
                catch (InterruptedException e)
                {
                    e.printStackTrace();
                }
    
                if (50 == i)
                {
                    break;
                }
            }
    
        }
    }
    复制代码

      该例子中,HelloThread类实现了Runnable接口,其中run()方法的主要工作是输出"Hello number: "字符串加数字i,并且同时递增i,当i到达50时,退出循环。

      main()方法中生成了一个HelloThread类的对象r,并且利用这个一个对象生成了两个线程。

      程序的执行结果是:顺次打印了0到49的数字,共50个数字。

      这是因为,i是成员变量,则HelloThread的对象r只包含这一个i,两个Thread对象因为由r构造,所以共享了同一个i

      当我们改变代码如下时(原先的成员变量i被注释掉,增加了方法中的局部变量i):

    复制代码
    public class HelloThreadTest
    {
        public static void main(String[] args)
        {
            HelloThread r = new HelloThread();
    
            Thread t1 = new Thread(r);
            Thread t2 = new Thread(r);
    
            t1.start();
            t2.start();
    
        }
    
    }
    
    class HelloThread implements Runnable
    {
        // int i;
        // 若i是成员变量,则HelloThread的对象r只包含这一个i,两个Thread对象因为由r构造,所以共享了同一个i
        // 打印结果是0到49的数字
        @Override
        public void run()
        {
            int i = 0;
            // 每一个线程都会拥有自己的一份局部变量的拷贝
            // 线程之间互不影响
            // 所以会打印100个数字,0到49每个数字都是两遍
            while (true)
            {
                System.out.println("Hello number: " + i++);
    
                try
                {
                    Thread.sleep((long) Math.random() * 1000);
                }
                catch (InterruptedException e)
                {
                    e.printStackTrace();
                }
    
                if (50 == i)
                {
                    break;
                }
            }
    
        }
    }
    复制代码

      如注释中所述,由于局部变量对于每一个线程来说都有自己的拷贝,所以各个线程之间不再共享同一个变量,输出结果为100个数字,实际上是两组,每组都是0到49的50个数字,并且两组数字之间随意地穿插在一起。 

    得到的结论如下:

      如果一个变量是成员变量,那么多个线程对同一个对象的成员变量进行操作时,它们对该成员变量是彼此影响的,也就是说一个线程对成员变量的改变会影响到另一个线程。

      如果一个变量是局部变量,那么每个线程都会有一个该局部变量的拷贝(即便是同一个对象中的方法的局部变量,也会对每一个线程有一个拷贝),一个线程对该局部变量的改变不会影响到其他线程。

    参考资料

      圣思园张龙老师Java SE系列视频教程。

  • 相关阅读:
    MFC tab页面中获到其它页面的数据
    sqlite数据库中"Select * From XXX能查到数据,但是Select DISTINCT group From xxx Order By group却查不出来
    关闭程序出现崩溃(exe 已触发了一个断点及未加载ucrtbased.pdb)
    springboot 通用Mapper使用
    springBoot 发布war包
    springCloud Zuul网关
    springboot hystrix turbine 聚合监控
    springBoot Feign Hystrix Dashboard
    springBoot Ribbon Hystrix Dashboard
    springBoot Feign Hystrix
  • 原文地址:https://www.cnblogs.com/wi100sh/p/4495739.html
Copyright © 2011-2022 走看看