java的线程中的Runnable

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

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

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接口实现类的对象,但是却被两个线程作为参数,啊啊。这个打印结果是什么玩意??

BaiduShurufa_2014-3-22_17-33-33

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

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。

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

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

你可能感兴趣的:(Runnable)