Runnable为什么能实现资源共享而Thread不能

做一下实验

class MyThread extends Thread{
    public void run() {
        System.out.println(this.hashCode());
    }
}

public class CreatThread {

    public static void main(String[] args) {
        // TODO Auto-generated method stub
        MyThread t1 = new MyThread();
        MyThread t2 = new MyThread();
        t1.start();
        t2.start();
    }
}

从这个结果可以得出

每次都是不同的对象来运行run()方法,不同对象,自然无法共享变量了

class MyThread implements Runnable{
    public void run() {
        System.out.println(this.hashCode());
    }
}

public class CreatThread {

    public static void main(String[] args) {
        // TODO Auto-generated method stub

        MyThread mt1 = new MyThread();

        Thread t1 = new Thread(mt1);
        Thread t2 = new Thread(mt1);
        t1.start();
        t2.start();    
    }

}

 

可得每次都是同一个对象运行run()方法,所以可以实现共享变量。

其实从构造器中也可以看出点东西来

public Thread() {
        init(null, null, "Thread-" + nextThreadNum(), 0);
    }


public Thread(Runnable target) {
        init(null, target, "Thread-" + nextThreadNum(), 0);
    }

两者的区别就是target的区别了,其他的都一样。

再次找下去

扫描二维码关注公众号,回复: 1473620 查看本文章
 private void init(ThreadGroup g, Runnable target, String name,
                      long stackSize) {
        init(g, target, name, stackSize, null, true);
    }


 private void init(ThreadGroup g, Runnable target, String name,
                      long stackSize, AccessControlContext acc,
                      boolean inheritThreadLocals) {
        if (name == null) {
            throw new NullPointerException("name cannot be null");
        }

        this.name = name;

        Thread parent = currentThread();
        SecurityManager security = System.getSecurityManager();
        if (g == null) {
            /* Determine if it's an applet or not */

            /* If there is a security manager, ask the security manager
               what to do. */
            if (security != null) {
                g = security.getThreadGroup();
            }

            /* If the security doesn't have a strong opinion of the matter
               use the parent thread group. */
            if (g == null) {
                g = parent.getThreadGroup();
            }
        }

        /* checkAccess regardless of whether or not threadgroup is
           explicitly passed in. */
        g.checkAccess();

        /*
         * Do we have the required permissions?
         */
        if (security != null) {
            if (isCCLOverridden(getClass())) {
                security.checkPermission(SUBCLASS_IMPLEMENTATION_PERMISSION);
            }
        }

        g.addUnstarted();

        this.group = g;
        this.daemon = parent.isDaemon();
        this.priority = parent.getPriority();
        if (security == null || isCCLOverridden(parent.getClass()))
            this.contextClassLoader = parent.getContextClassLoader();
        else
            this.contextClassLoader = parent.contextClassLoader;
        this.inheritedAccessControlContext =
                acc != null ? acc : AccessController.getContext();
        this.target = target;//这里应该就是唯一的区别了,初始化的target不同
        setPriority(priority);
        if (inheritThreadLocals && parent.inheritableThreadLocals != null)
            this.inheritableThreadLocals =
                ThreadLocal.createInheritedMap(parent.inheritableThreadLocals);
        /* Stash the specified stack size in case the VM cares */
        this.stackSize = stackSize;

        /* Set thread ID */
        tid = nextThreadID();
    }

然后,target的不同对run()的直接影响我并没有找到......

start()到了start0(),是native方法.....然后就没有然后了。

如果哪位大神能直接的验证这个,请一定要告诉我

猜你喜欢

转载自www.cnblogs.com/curator/p/9140304.html