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

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© trhthyj 中级黑马   /  2014-4-29 15:19  /  2122 人查看  /  10 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

  1. class Ticket extends Thread
  2. {
  3.         private static int tick=100;//这里为什么非得加static才可以共同卖100张票??
  4.         public void run()
  5.         {
  6.                 while(true)
  7.                 {
  8.                         if(tick>0)
  9.                         {
  10.                                 System.out.println(Thread.currentThread().getName()+"   "+tick--);
  11.                         }
  12.                 }
  13.         }
  14. }

  15. class TicketDemo
  16. {
  17.         public static void main(String[] args)
  18.         {
  19.                 Ticket t1=new Ticket();
  20.                 Ticket t2=new Ticket();
  21.                 Ticket t3=new Ticket();
  22.                 Ticket t4=new Ticket();
  23.                 t1.start();
  24.                 t2.start();
  25.                 t3.start();
  26.                 t4.start();
  27.         }
  28. }
复制代码

10 个回复

倒序浏览
本帖最后由 张然龙 于 2014-4-29 15:52 编辑

你开启的四个线程 ,new 了四个对象 ,
  1. Ticket t1=new Ticket();
  2. Ticket t2=new Ticket();
  3. Ticket t3=new Ticket();
  4. Ticket t4=new Ticket();
复制代码





也就是说 你的内存堆内存中存在着四个对象的引用,这四个对象的引用各有一个tick变量 ,虽说是相同名字,但是却不是一个变量哦。。
如果想解决这个问题有两种方式,一种是像你说的 把tick设置成静态变量
第二种方法就是创建Ticket  tic=new Ticket();对象 ,然后Thread  thread=new Thread(tic);,然后  thread.start();就可以让四个线程共同拥有一个对象,达到同步的目的,代码如下↓

  1. class TicketDemo
  2. {
  3.         public static void main(String[] args)
  4.         {
  5.                 Ticket  tic=new Ticket();
  6.                 Thread  thread1=new Thread(tic);
  7.                 Thread  thread2=new Thread(tic);
  8.                 Thread  thread3=new Thread(tic);
  9.                 Thread  thread4=new Thread(tic);
  10.                 thread1.start();
  11.                 thread2.start();
  12.                 thread3.start();
  13.                 thread4.start();      
  14.         }
  15. }
复制代码









评分

参与人数 1技术分 +1 收起 理由
菜小徐 + 1

查看全部评分

回复 使用道具 举报
static修饰成员变量,表示该变量被这个类的所有对象共享。内存中只有这一份数据:100张票。
               Ticket t1=new Ticket();
               Ticket t2=new Ticket();
                Ticket t3=new Ticket();
                Ticket t4=new Ticket();
上边四个语句创建四个变量,共享一份资源:100张票。
如果不使用静态,四个对象要创建四份资源:每个对象100张票。在多线程环境下,可以不用静态,使用同步:
代码如下:
class Ticket extends Thread
{
        private static int tick=100;//这里为什么非得加static才可以共同卖100张票??
        public synchronized void run()//使用synchronized
        {
                while(true)
                {
                        if(tick>0)
                        {
                                System.out.println(Thread.currentThread().getName()+"   "+tick--);
                        }
                }
        }
}

class TicketDemo
{
        public static void main(String[] args)
        {
                Ticket t1=new Ticket();
                Ticket t2=new Ticket();
                Ticket t3=new Ticket();
                Ticket t4=new Ticket();
                t1.start();
                t2.start();
                t3.start();
                t4.start();
        }
}

评分

参与人数 1技术分 +1 收起 理由
菜小徐 + 1

查看全部评分

回复 使用道具 举报
static修饰变量表示这个tick变量属于类的,是类的所有对象共享的,如果不要static就相当于是实例变量,每个类都有自己各自的tick,并且tick都等于100,本题就相当于4个线程都在各自卖自己的100张票,这就不能实现共享数据了,也就不能一起卖这100张票了。
回复 使用道具 举报
不静态的话,new了四个对象就会有四个tick=100,虽然你启用了四个线程但是他们都是各自忙活各自的run方法
回复 使用道具 举报
static修饰后就是静态变量了,不管你创建多少个对象,他的个数是唯一的
回复 使用道具 举报
加static叫静态成员,也叫类成员。不加叫实例成员。实例成员每个对象都有自己的实例成员,但类成员是所有对象共共享的,改变其中一个对象的类成员,其他对象的类成员也随之改变。
实例成员和对象的生命周期相同,而类成员和类的生命周期相同。实例成员必须通过对象名进行访问,类成员可以通过类名和对象名进行访问。
回复 使用道具 举报
lzhuas 中级黑马 2014-4-29 16:37:20
8#
你要好好看视频static特点:
1,随着类的加载而加载,其生命周期最长。注意:耗内存的哦

2,优先于对象的存在。要明确了,静态先存在,对象是后存在的
3,被所以对象所共享的。你这里就很明显了,你一静态,所有对象都只能使用100这个共同数据了
4,可以直接被类名调用。这里指的是静态方法。
回复 使用道具 举报
大象 中级黑马 2014-4-29 16:39:13
9#
static 是全局变量,生命周期最长,而且是放在方法共享区内存里面的,也就是共享的数据,当然是唯一的。 所以虽然你创建了4个线程对象,但是ticket数据还是共享的。 接下来,如果你不加线程锁的话,有可能打出-1,-2的票来哦。所以你还要加同步锁才行。
回复 使用道具 举报
static修饰的··是常量。。
回复 使用道具 举报
感谢大家的回答,一起为了梦想努力!
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马