java的线程中的Runnable

                  在java中可有两种方式实现多线程,一种是继承Thread类,一种是实现Runnable接口;Thread类是在java.lang包中定义的。一个类只要继承了Thread类同时覆写了本类中的run()方法就能够实现多线程操做了,可是一个类只能继承一个父类,这是此方法的局限。java

可是实际在使用过程你会发现一些令你迷惑的问题,就来看下吧下面的代码:多线程

public class SeThread implements Runnable {

	private int i;

	@Override
	public void run() {
		for (; i < 20; i++) {

				System.out.println(Thread.currentThread().getName() + "  i= "+ i);


		}

	}

	public static void main(String[] args) {
		for (int i = 0; i < 100; i++) {
			if (i == 20) {
				SeThread st = new SeThread();
				new Thread(st, "线程1").start();
				new Thread(st, "线程2").start();
			}
		}
	}
	
	

}

 

能够看到,st是一个Runnable接口实现类的对象,可是却被两个线程做为参数,啊啊。这个打印结果是什么玩意??ide

BaiduShurufa_2014-3-22_17-33-33

  看到这或许你已经猜到了,这个是两个Thread的外壳下竟然是同一颗跳到的Runnable心,那么仍是看下Thread的实现吧。this

public
class Thread implements Runnable {

 public synchronized void start() {
       
        group.add(this);

        boolean started = false;
        try {
            start0();
            started = true;
        } finally {
            try {
                if (!started) {
                    group.threadStartFailed(this);
                }
            } catch (Throwable ignore) {
                /* do nothing. If start0 threw a Throwable then
                  it will be passed up the call stack */
            }
        }
    }

    private native void start0();

 @Override
    public void run() {
        if (target != null) {
            target.run();
        }
    }

//……
}

其实,Thread就是Runnable实现类,在调用start过程当中,咱们能够知道它实现调用的是一个start0()这个本地方法,这个从咱们之前开发用的方法可知,确定是在CPU资源分配过程当中的某个时机调用了Thread的run()方法了,而run()方法实现的执行体就是传入的Runnable对象的runnable。.net

因此两个Thread的执行体,就是同一个runnale对象了,这个看上去是两个线程,可实际上只有一个执行体那就是st对象啦,打印结果确定是如上图看到的那样了。线程

其实这个打印有两个0,可知线程未同步,咱们能够在处理打印这个方法作个同步修饰synchronized,这样就能够正确的打印从0到99啦。code

相关文章
相关标签/搜索