iava多线程详解(2)-成员变量与局部变量访问

有两段代码

1.线程访问成员变量

public class FirstThreadTest
{
    public static void main(String[] args)
    {
        FirstThread r = new FirstThread();

        Thread t1 = new Thread(r);
        Thread t2 = new Thread(r);

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

    }
}

/**
* 第一个线程程序
*/
class FirstThread implements Runnable { int i; @Override public void run() { while (true) { System.out.println("number of: " + i++); try { Thread.sleep((long) Math.random() * 1000); } catch (InterruptedException e) { e.printStackTrace(); } if (50 == i) { break; } } } }

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

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

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

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

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

2.线程访问局部变量

public class FirstThreadTest
{
 public static void main(String[] args)
    {
        HelloThread r = new HelloThread();

        Thread t1 = new Thread(r);
        Thread t2 = new Thread(r);

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

    }

}


 /**
 * 通过Runnable接口实现线程
 */

class FirstThread implements Runnable

{
    // int i;
    // 若i是成员变量,则FirstThread共享了同一个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;
            }
        }

    }
 }

结论:

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

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

原文地址:https://www.cnblogs.com/weiguo21/p/4753437.html