public class Thread implements Runnable { //... /* For autonumbering anonymous threads. */ private static int threadInitNumber; /* What will be run. */ private Runnable target; //... /** * If this thread was constructed using a separate * <code>Runnable</code> run object, then that * <code>Runnable</code> object's <code>run</code> method is called; * otherwise, this method does nothing and returns. * <p> * Subclasses of <code>Thread</code> should override this method. * * @see #start() * @see #stop() * @see #Thread(ThreadGroup, Runnable, String) */ @Override public void run() { if (target != null) { target.run(); } } }
于是找到了造成以上三个程序结果的原因:
注释中的What will be run 是一个 名为target的实现了Runnable接口的对象 。用有参(有target)构造函数构造一个Thread,该线程的run()方法即执行target的run()方法。如果用有参构造函数创建三个线程,并且传入的是同一个实现了Runnable接口的对象,那么这三个线程中的target指向同一个对象。所以这三个线程的对同一个对象进行操作,从而实现资源共享的效果。
/** * Initializes a Thread. * * @param g the Thread group * @param target the object whose run() method gets called * @param name the name of the new Thread * @param stackSize the desired stack size for the new thread, or * zero to indicate that this parameter is to be ignored. * @param acc the AccessControlContext to inherit, or * AccessController.getContext() if null * @param inheritThreadLocals if {@code true}, inherit initial values for * inheritable thread-locals from the constructing thread */ private void init(ThreadGroup g, Runnable target, String name, long stackSize, AccessControlContext acc, boolean inheritThreadLocals) { //... //当然要包含这句 this.target = target; //... }