java面试系列--J2SE基础(六)

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/weisong530624687/article/details/79202692

21. 实现多线程的两种方法:Thread与Runable。

Thread是Class,要求单一继承,不能再继承其他类,有一定的局限性;

Runable是接口Inteface,接口可以实现多个,方便拓展。

在Java当中,线程通常都有五种状态,创建、就绪、运行、阻塞和死亡。
  第一是创建状态。在生成线程对象,并没有调用该对象的start方法,这是线程处于创建状态。
  第二是就绪状态。当调用了线程对象的start方法之后,该线程就进入了就绪状态,但是此时线程调度程序还没有把该线程设置为当前线程,此时处于就绪状态。在线程运行之后,从等待或者睡眠中回来之后,也会处于就绪状态。
  第三是运行状态。线程调度程序将处于就绪状态的线程设置为当前线程,此时线程就进入了运行状态,开始运行run函数当中的代码。
  第四是阻塞状态。线程正在运行的时候,被暂停,通常是为了等待某个时间的发生(比如说某项资源就绪)之后再继续运行。sleep,suspend,wait等方法都可以导致线程阻塞。
  第五是死亡状态。如果一个线程的run方法执行结束或者调用stop方法后,该线程就会死亡。对于已经死亡的线程,无法再使用start方法令其进入就绪。

1.start()方法来启动线程,真正实现了多线程运行。这时无需等待run方法体代码执行完毕,可以直接继续执行下面的代码;通过调用Thread类的start()方法来启动一个线程, 这时此线程是处于就绪状态, 并没有运行。 然后通过此Thread类调用方法run()来完成其运行操作的, 这里方法run()称为线程体,它包含了要执行的这个线程的内容, Run方法运行结束, 此线程终止。然后CPU再调度其它线程。
2.run()方法当作普通方法的方式调用。程序还是要顺序执行,要等待run方法体执行完毕后,才可继续执行下面的代码; 程序中只有主线程——这一个线程, 其程序执行路径还是只有一条, 这样就没有达到写线程的目的。

下面通过几个代码实例了解执行过程:

/**
 * 
 * @author:Mars
 * @version Revision 1.0.0
 * @see:
 * @创建日期:2018年1月30日
 * @功能说明:
 */
public class ThreadDemo extends Thread {
    int j = 0;
    @Override
    public void run() {
        while (j<100) {
            System.err.println("ThreadDemo...."+j);
            j++;
        }
    }
}
/**
 * 
 * @author:Mars
 * @version Revision 1.0.0
 * @see:
 * @创建日期:2018年1月30日
 * @功能说明:
 */
public class RunnableDemo implements Runnable {

    int i = 0;
    @Override
    public void run() {
        while (i<100) {
            System.err.println("RunnableDemo..."+i);
            ++i;
        }
    }
    
    public static void main(String[] args) {
        //写法一:
        RunnableDemo runnableDemo = new RunnableDemo();
//        new Thread(runnableDemo).start();
        
        ThreadDemo threadDemo = new ThreadDemo();
//        threadDemo.start();//run();
        
        //写法二:
        threadDemo.run();
        runnableDemo.run();
    }

}

下图主要说明 继承Thread,其实也是实现了Runnable接口,因为父类实现了该接口。


分别创建了2个线程实例,然后启动他们,具体看清各种启动方式的区别,两个均start启动,体现了线程此刻就绪状态,一旦有资源,便开始执行,实质就是cpu的轮询切换对应到线程的轮询切换执行。


方法二执行方式:第一个run,第二start,结果并未交叉执行,因为一旦run启动,线程直接开始执行,不再等待,直到完毕。可以理解为他就是正常的程序,非多线程实现方式。

切换方式后,依旧交叉执行,因为第一个首先会就绪好,然后执行到第二个,一有资源释放,第一个立刻执行。

最后,都run的时候,结果也一样,线性执行。










猜你喜欢

转载自blog.csdn.net/weisong530624687/article/details/79202692