黑马程序员技术交流社区

标题: 一个关于线程的问题? [打印本页]

作者: 薛振宇    时间: 2014-7-18 20:17
标题: 一个关于线程的问题?
首先,线程的两种创建方法:1实现Runnable接口,2继承Thread类,还记得售票的例子吗。
public static void main(String[] args) {
//            T1 t1=new T1();
//            T1 t2=new T1();
//            T1 t3=new T1();
//            t1.start();
//            t2.start();
//            t3.start();
                T2 t1=new T2();
//                T2 t2=new T2();
//                T2 t3=new T2();
            Thread a1=new Thread(t1);
            Thread a2=new Thread(t1);
            Thread a3=new Thread(t1);
            a1.start();
            a2.start();
            a3.start();
        }
       
       
}
   class T1 extends Thread{

        private static int tick=10;
        //private int tick=10;
       
        public void run() {
                while(tick>0){
                        System.out.println(this.getName()+":"+tick--);
                       
                }
        }
          
   }
class T2 implements Runnable{
        private int tick=10;
        @Override
        public void run() {
               
                while(tick>0){
                        System.out.println(Thread.currentThread().getName()+":"+tick--);
                       
                }
        }
       
}

当使用继承类的方法时,创建的Thread对象是不共享tick这个变量的。
但是使用实现接口(实现的类是T2)的方法时,当定义多个T2对象时,每个对象分别作为参数传入Thread的构造函数中创建Thread对象,仍然不共享数据,只用一个T2对象创建多个thread时,为什么会共享数据啊?其中的原理是什么啊?

作者: 薛振宇    时间: 2014-7-18 20:24
强烈希望大神解答
作者: 薛振宇    时间: 2014-7-18 20:30
我在想是不是,这些通过一个T2对象创建的Thread对象,执行的是同一个run()方法,就是在执行同一个循环啊
作者: 薛振宇    时间: 2014-7-18 20:33
还是,这个tick变量变得类似于静态变量
作者: 晏敏    时间: 2014-7-18 20:44
第一种是创建了三个继承了Thread类的不同对象,每个对象的线程相互独立,当然不会共享;而第二种只创建了一个实现Runnable接口的对象,并用这一个对象创建了三个线程,它们共用这一个对象!
作者: ddewym123    时间: 2014-7-18 21:08
本帖最后由 ddewym123 于 2014-7-18 21:10 编辑

你传进Thread的都是同一个T2对象t1,那a1,a2,a3的run方法操作的都是t1的tick变量,当然是共享的了
作者: 薛振宇    时间: 2014-7-18 21:40
我知道你说的,我想知道的是它内部发什么了什么,尽管,是只传入了一个T2对象,但是生成的几个Thread对象不一样的啊,为什么,就能共享变量了吗
作者: 薛振宇    时间: 2014-7-18 22:20
晏敏 发表于 2014-7-18 20:44
第一种是创建了三个继承了Thread类的不同对象,每个对象的线程相互独立,当然不会共享;而第二种只创建了一 ...

这只是Thread独有的,还是只要有这种情况,例如:A类的构造函数中带有B对象的参数,那么如果用一个B对象构建的A对象,他们共享B对象中成员变量吗
作者: 薛振宇    时间: 2014-7-18 22:31
薛振宇 发表于 2014-7-18 22:20
这只是Thread独有的,还是只要有这种情况,例如:A类的构造函数中带有B对象的参数,那么如果用一个B对象 ...

我实验了一下,好像不是这样的,这种现象时Thread独有的:我的代码
package cn.xue.thread;

public class Test4 {

        /**
         * @param args
         */
        public static void main(String[] args) {
          B b=new B();
          A a1=new A(b);
          A a2=new A(b);
      a1.add();
      System.out.print(a2.b.getA());
        }

}
class A{
        public B b=new B();
    public A(B b){
           
    }
    public void add(){
            b.setA(b.getA()+1);
    }
}
class B{
        public int a=10;
        public int getA(){
                return a;
        }
        public void setA(int a){
                this.a=a;
        }
}
能不能达到实验效果啊
作者: 晏敏    时间: 2014-7-18 22:41
不清楚Thread中Runnable属于什么情况。写了一个程序,程序里是A中含有B这个field这种情况。
这样情形下,共享这一个变量。
public class Main {

        public static void main(String[] args) {
                // TODO Auto-generated method stub
                Target t=new Target();
                Person p1=new Person(t);
                Person p2=new Person(t);
                t.setNum(4);
                //都输出4
                System.out.println(p1.get());
                System.out.println(p2.get());
        }
       
       
       

}
class Target{
        private int num=2;

        public int getNum() {
                return num;
        }

        public void setNum(int num) {
                this.num = num;
        }
}

class Person{
        private Target t;
        public Person(Target t){
                this.t=t;
        }
       
        public int get(){
                return t.getNum();
        }
}
作者: 薛振宇    时间: 2014-7-18 22:51
晏敏 发表于 2014-7-18 22:41
不清楚Thread中Runnable属于什么情况。写了一个程序,程序里是A中含有B这个field这种情况。
这样情形下,共 ...

你试验我的代码了吗

作者: 薛振宇    时间: 2014-7-18 23:56
咱们两个代码的区别是,你是在Target里完成的数据更改,而我的是在A里完成的
作者: 晏敏    时间: 2014-7-19 08:30
嗯,你代码里的效果是这样,确实两者共享同一个数字,Thread源码里也有一个Runnable对象,应该和你这个相同,所以这样应该是共享的效果。
作者: 薛振宇    时间: 2014-7-19 10:45
晏敏 发表于 2014-7-19 08:30
嗯,你代码里的效果是这样,确实两者共享同一个数字,Thread源码里也有一个Runnable对象,应该和你这个相同 ...

我明白了,传的是个引用,而不是一个对象的副本,所以改变引用的值,其实就是改变相应对象的值




欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) 黑马程序员IT技术论坛 X3.2