A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© 任雷彬 中级黑马   /  2012-10-31 10:11  /  2044 人查看  /  4 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

在毕老师视频中卖票的多线程举例中。
用static修饰后的成员变量可以被创建的多个线程共享数据。而未被static修饰的成员变量,却会各自运行创建的线程。
这仅仅是因为static修饰的成员变量存在于方法共享区吗?还是应该怎么理解这个变化呢?

class Ticket implements Runnable//extends Thread
{
        private   static int tick = 100;//static修饰与不用static修饰结果不一样。static修饰可以共享数据
        public void run()                  //为什么呢?
        {
                while(true)
                {
                        if(tick>0)
                        {
                                System.out.println(Thread.currentThread().getName()+"....sale : "+ tick--);
                        }
                }
        }
}


class  TicketDemo
{
        public static void main(String[] args)
        {

                Ticket t = new Ticket();

                Thread t1 = new Thread(t);//创建了一个线程;
                Thread t2 = new Thread(t);//创建了一个线程;
                Thread t3 = new Thread(t);//创建了一个线程;
                Thread t4 = new Thread(t);//创建了一个线程;
                t1.start();
                t2.start();
                t3.start();
                t4.start();


                        }
}

         我认为创建一个新的线程都会访问数据,static修饰后会共享,为什么?我有些不理解。

评分

参与人数 1技术分 +1 收起 理由
刘芮铭 + 1

查看全部评分

4 个回复

倒序浏览
这是java的内存机制决定的,java在内存中开辟了五片空间,用于存储不同的数据
方法区中存储方法和共享数据,以便于节省内存空间,至于为什么会这样,这是java设计者设计的,底层原理,不必深究。
用static修饰后就不会跟对象走,无论创建多少个对象,它也只有一份,存于方法区。

评分

参与人数 1技术分 +1 收起 理由
刘芮铭 + 1

查看全部评分

回复 使用道具 举报
static修饰的变量是放在共享区时,就不受对象控制了,这时所有线程任务在执行时用的是一个数据;
如果没有被修饰,这时变量放在堆内存中,当创建带有执行任务的线程对象时,每创建一次,就会利用新创建的对象身上所拥有的属性。

评分

参与人数 1技术分 +1 收起 理由
刘芮铭 + 1

查看全部评分

回复 使用道具 举报
这个问题就需要了解内存的分类了,我做了一下总结:
堆区:

①存储的全部是对象,每一个对象都包含一个与之相对应的class的信息。(class的目的是得到操作指令)

②jvm中只有一个堆区被所有的线程共享,堆中不存放基本数据类型和自定义的对象的引用(不是对象),对象都是存放在堆区中的

栈区:

①每个线程都包含一个栈区,栈中只保存基本数据类型的对象和自定义数据类型的引用(不是对象),对象都放在堆区中。

②每个栈中的数据都是私有的,其他栈不能访问。

③栈区分为3个部分:基本类型变量区,执行环境上下文、操作指令区。

方法区:

①又叫静态区,和堆一样,被所有的线程共享。方法区包含所以的class和static变量。

②方法去包含的都是整个程序中永远唯一的元数,入class和static变量。

评分

参与人数 1技术分 +1 收起 理由
刘芮铭 + 1

查看全部评分

回复 使用道具 举报
之前没有加static时候,创建一个对象这个对象就拥有了100张票。
因为static修饰的变量在方法加载之前就已经进入了内存,之后建立的线程所使用的run方法调用的都是这一个静态的ticket。
就像毕老师说的,理解了静态static的用法就会想到,可以回头看下有关静态的视频再理解下。

评分

参与人数 1技术分 +1 收起 理由
刘芮铭 + 1

查看全部评分

回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马