做一下实验
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的区别了,其他的都一样。
再次找下去
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方法.....然后就没有然后了。
如果哪位大神能直接的验证这个,请一定要告诉我