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

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© 李贺晓 中级黑马   /  2012-11-14 16:35  /  1729 人查看  /  3 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

本帖最后由 李贺晓 于 2012-11-14 16:38 编辑

在一本资料上看到说是创建多线程类是继承Thread类的话,此方法创建的多条线程不可共享线程类的的实例属性
而通过implements实现Runnable接口时,此方法创建的多条线程是可以共享线程类的实例属性的
继承:
class FirstThread extends Thread
{
private int i;
public void run()//重写run方法
{
  for(int i=0;i<100;i++)
  {
   //当线程类继承Thread时,可以直接调用getName()方法来获取当前线程的名称
   //如果想获取当前线程的名称,用this即可
   System.out.println(this.getName()+"......."+i);
  }
}
public static void main(String[] args)
{
  for(int i=0;i<100;i++)
  {
   //调用Thread的currentThread()方法获取当前线程
   System.out.println(Thread.currentThread().getName()+".."+i);
   if(i==20)
   {
    //创建并启动第一条线程
    new FirstThread().start();
    //创建并启动第二条线程
    new FirstThread().start();
   }
  }
}
}


实现:
class  SecondThread implements Runnable
{
private int i;
public static void main(String[] args)
{
  
  for(int i=0;i<100;i++)
  {
   System.out.println(Thread.currentThread().getName()+"======"+i);
   if(i==20)
   {
    SecondThread st=new SecondThread();
    new Thread(st,"线程one").start();
    new Thread(st,"线程two").start();
   }
  }
}
public void run()
{
  for(int i=0;i<100;i++)
  {
   System.out.println(Thread.currentThread().getName()+"-------"+i);
  }
}
}
按资料说上的,第二种方法运行后应该出现的结果是线程one和线程two两者是共享i值的,但是运行的结果两种方法是一样的,都是随机出现的,第二种也是每个线程都是从0到100,线程one和线程two并没有共享i,这个是怎么回事?是资料上错误了,还是我的程序有问题
按资料上说第二种方法的运行结果应该是这样的

实现.png (115.15 KB, 下载次数: 55)

实现.png

点评

加上多线程安全锁去试试,  发表于 2012-11-14 17:03

评分

参与人数 1技术分 +1 收起 理由
古银平 + 1 赞一个!

查看全部评分

3 个回复

倒序浏览
学习中!!!!
回复 使用道具 举报
资料上的意思应该是实现可以进行同步操作,通过同步代码快,同步函数对共享数据进行操作。而继承则没有,所以应该加上同步操作
回复 使用道具 举报
1、实际上Thread类和Runnable接口之间在使用上是有区别的,如果一个类继承Thread类,则不适合于多个线程共享资源,而实现了Runnable接口,就可以方便地实现资源的共享。
(1)继承Thread类不能资源共享(代码体现如下)
    class MyThread extends Thread            //继承Thread类
       {
        private int ticket = 5;              //一共5张票
        public void run(){                    //重写run()方法
                for(int i=0;i<100;i++){
                             if(ticket>0){             //判断是否有剩余票
                                       System.out.println("卖票:ticket="+ticket--);
                                   }
                        }
                  }
        }
public class ThreadDemo1{
      public static void main(String[] args){
              MyThread mt1 = new MyThread();
                  MyThread mt2 = new MyThread();
                  MyThread mt3 = new MyThread();
                                    mt1.start();
                                    mt2.start();
                  mt3.start();
          }
}
运行结果:
卖票:ticket = 5
卖票:ticket = 4
卖票:ticket = 3
卖票:ticket = 2
卖票:ticket = 1

卖票:ticket = 5
卖票:ticket = 4
卖票:ticket = 3
卖票:ticket = 2
卖票:ticket = 1

卖票:ticket = 5
卖票:ticket = 4
卖票:ticket = 3
卖票:ticket = 2
卖票:ticket = 1

以上程序通过Thread类实现多线程,程序中启动了3个线程,但是3个线程却分别卖了各自的5张票,并没有达到资源共享的目的。

(2)实现Runnable接口可以实现资源共享(代码体现如下)
class MyThread implements Runnable        //实现Runnable接口
{
        private int ticket = 5;               //一共5张票
        public void run(){                    //重写run()方法
                for(int i=0;i<100;i++){
                             if(ticket>0){             //判断是否有剩余票
                                       System.out.println("卖票:ticket="+ticket--);
                                 }
                        }
          }
}
public class RunnableDemo2{
      public static void main(String[] args){
               MyThread my = new MyThread();
                   new MyThread(my).start();
                   new MyThread(my).start();
                   new MyThread(my).start();
          }
}
运行结果:
卖票:ticket = 5
卖票:ticket = 4
卖票:ticket = 3
卖票:ticket = 2
卖票:ticket = 1

从程序的运行结果中可以清楚的发现,虽然启动了3个线程,但是3个线程一共才卖了5张票,即ticket属性被所有的线程对象共享。
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马