原文网址: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系列视频教程。

【转】Java 多线程(四) 多线程访问成员变量与局部变量的更多相关文章

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

    有两段代码 1.线程访问成员变量 public class FirstThreadTest { public static void main(String[] args) { FirstThread ...

  2. java类与对象_成员变量和局部变量区别

    成员变量和局部变量:1.成员变量:再类中定义,用来描述对象将要有什么.2.局部变量:在类的方法中定义,在方法中临时保存数据.区别:1.作用域不同:  局部:仅限于定义它的方法  成员:整个类中都是可见 ...

  3. Java 多线程(四) 多线程访问成员变量与局部变量

    先看一个程序例子: public class HelloThreadTest { public static void main(String[] args) { HelloThread r = ne ...

  4. Java 访问限制符 在同一包中或在不同包中:使用类创建对象的权限 & 对象访问成员变量与方法的权限 & 继承的权限 & 深入理解protected权限

    一.实例成员与类成员 1. 当类的字节码被加载到内存, 类中类变量.类方法即被分配了相应内存空间.入口地址(所有对象共享). 2. 当该类创建对象后,类中实例变量被分配内存(不同对象的实例变量互不相同 ...

  5. Java反射理解(四)-- 获取成员变量构造函数信息

    Java反射理解(四)-- 获取成员变量构造函数信息 步骤 获取成员变量信息: obj.getClass() 获取类类型对象 成员变量也是对象,java.lang.reflect.Field 类中封装 ...

  6. JAVA类与对象(四)----成员变量与局部变量 、成员方法、构造方法

    类体中的变量分为两部分.变量定义部分定义的变量为类的成员变量,在方法体中定义的变量和方法中涉及的变量称为局部变量. 成员变量和局部变量的区别: (1).成员变量在整个类中都有效,局部变量只在定义它的方 ...

  7. java 继承访问成员变量

    package java09; //创建父类 public class Fu { int numFu = 10; int num =100; public void methodFu(){ Syste ...

  8. java 线程---成员变量与局部变量

    关于成员变量与局部变量: 如果一个变量是成员变量,那么多个线程对同一个对象的成员变量进行操作时,他们对该成员变量是彼此影响的(也就是说一个线程对成员变量的改变会影响到另一个线程) . 如果一个变量是局 ...

  9. 【java基础】成员变量和局部变量

    成员变量和局部变量 根据定义变量位置的不同,可以将变量分为成员变量和局部变量        成员变量是在类范围内定义的变量        局部变量是在一个方法内定义的变量   成员变量可以分为:   ...

随机推荐

  1. AngularJs学习之ng-repeat

    ng-repeat用来遍历一个集合或为集合中的每个元素生成一个模板实例.集合中的每个元素都会被赋予自己的模板和作用域.同时每个模板实例的作用域中都会暴露一些特殊的属性. $index:遍历的进度(0 ...

  2. YII框架路由和URL生成

    路由和URL生成 当一个YII应用开始处理一个请求的时候,它首先要做的便是将请求的URL转化成一个路由.路由的作用是用于后续实例化相应的控制器和操作,以便处理请求,整个处理过程便叫做路由.路由的逆过程 ...

  3. ASP.Net MVC 之FileResult

    FileResult是一个基于文件的ActionResult,利用FileResult我们可以很容易地将从某个物理文件的内容响应给客户端.ASP.NET MVC定义了三个具体的FileResult,分 ...

  4. 关于在repeater中的checkbox实行多选和全选

    今天项目中用到这一块,是一个b2b商城,业务是别人给客户留言后,客户从会员中心的留言管理中查看,用checkbox实行多选和全选后进行批量审核 首先在checkbox后加个hidden,作用见代码: ...

  5. Linq使用GroupBy筛选数据

    StringBuilder sb = new StringBuilder(); List<IGrouping<string, modle>> listRepeat = mode ...

  6. WordPress程序流程分析

    index.php 统一入口文件 包含wp-blog-heaer.php 包含wp-load.php 包含wp-config.php 数据库.语言包配置等 包含wp-setting.php 对各种运行 ...

  7. oracle 分布式数据库

    分布式数据库的数据库链路是单向的

  8. Java内存分配和GC

    Java内存分配和回收的机制概括的说,就是:分代分配,分代回收. 对象将根据存活的时间被分为:年轻代(Young Generation).年老代(Old Generation).永久代(Permane ...

  9. 你好,C++(26)如何与函数内部进行数据交换?5.1.3 函数参数的传递

    5.1.3  函数参数的传递 我们知道,函数是用来完成某个功能的相对独立的一段代码.函数在完成这个功能的时候,往往需要外部数据的支持,这时就需要在调用这个函数时向它传递所需要的数据它才能完成这个功能获 ...

  10. jQuery get/post区别及contentType取值

    1.GET访问 浏览器 认为 是等幂的 就是 一个相同的URL 只有一个结果[相同是指 整个URL字符串完全匹配]所以 第二次访问的时候 如果 URL字符串没变化浏览器是直接拿出了第一次访问的结果,表 ...