zoukankan      html  css  js  c++  java
  • Java -- Thread中start和run方法的区别

    一、认识Thread的 start() 和 run()

    1。start():

    我们先来看看API中对于该方法的介绍:

         使该线程开始执行;Java 虚拟机调用该线程的 run 方法。

         结果是两个线程并发地运行;当前线程(从调用返回给 start 方法)和另一个线程(执行其 run 方法)。

         多次启动一个线程是非法的。特别是当线程已经结束执行后,不能再重新启动。

    用start方法来启动线程,真正实现了多线程运行,这时无需等待run方法体代码执行完毕而直接继续执行下面的代码。通过调用Thread类的 start()方法来启动一个线程,这时此线程处于就绪(可运行)状态,并没有运行,一旦得到cpu时间片,就开始执行run()方法,这里方法 run()称为线程体,它包含了要执行的这个线程的内容,Run方法运行结束,此线程随即终止。

    2。run():

    我们还是先看看API中对该方法的介绍:

          如果该线程是使用独立的 Runnable 运行对象构造的,则调用该 Runnable 对象的 run 方法;否则,该方法不执行任何操作并返回。

        Thread 的子类应该重写该方法。

    run()方法只是类的一个普通方法而已,如果直接调用Run方法,程序中依然只有主线程这一个线程,其程序执行路径还是只有一条,还是要顺序执行,还是要等待run方法体执行完毕后才可继续执行下面的代码,这样就没有达到写线程的目的。

    3。总结:

    调用start方法方可启动线程,而run方法只是thread的一个普通方法调用,还是在主线程里执行。

    二、代码实例:

    public static void main(String args[]) {
    		Thread t = new Thread() {
    			public void run() {
    				pong();
    			}
    		};
    		t.start();
    		System.out.print("ping");
    	}
    
    	static void pong() {
    		System.out.print("pong");
    	}

    输出结果: pingpong

    public static void main(String args[]) {
    		Thread t = new Thread() {
    			public void run() {
    				pong();
    			}
    		};
    		t.run();
    		System.out.print("ping");
    	}
    
    	static void pong() {
    		System.out.print("pong");
    	}

    输出结果:pongping

    通过以上两个程序实例,可以很容易的区分出start()方法和run()方法的区别:

    t.start(); 该行代码相当于是启动线程,

    t.run(); 该行代码相当于是使用t这个类中的run方法而已.

    三、线程状态说明:

    线程状态从大的方面来说,可归结为:初始状态、可运行状态、不可运行状态和消亡状态,具体可细分为上图所示7个状态,说明如下:

    1)线程的实现有两种方式,一是继承Thread类,二是实现Runnable接口,但不管怎样,当我们new了thread实例后,线程就进入了初始状态;

    2)当该对象调用了start()方法,就进入可运行状态;

    3)进入可运行状态后,当该对象被操作系统选中,获得CPU时间片就会进入运行状态;

    4)进入运行状态后case就比较多,大致有如下情形: ﹒run()方法或main()方法结束后,线程就进入终止状态; 当线程调用了自身的sleep()方法或其他线程的join()方法,就会进入阻塞状态(该状态既停 止当前线程,但并不释放所占有的资源)。当

    sleep()结束或join()结束后,该线程进入可运行状态,继续等待OS分配时间片; 当线程刚进入可运行状态(注意,还没运行),发现将要调用的资源被锁牢(synchroniza,lock),将会立即进入锁池状态,等待获取锁标记(这时的锁池里也许已经有了其他线

    程在等待获取锁标记,这时它们处于队列状态,既先到先得),一旦线程获得锁标记后,就转入可运行状态,等待OS分配 CPU时间片; 当线程调用wait()方法后会进入等待队列(进入这个状态会释放所占有的所有资源,与阻塞状态不同),进入这个状态后,

    是不能自动唤醒的,必须依靠其他线程调用notify()或notifyAll()方法才能被唤醒(由于notify()只是唤醒一个线程,但我们由不能确定具体唤醒的是哪一个线程,也许我们需要唤醒的线程不能够被唤醒,因此在实际使用时,一般都用notifyAll()方法,唤醒

    有所线程),线程被唤醒后会进入锁池,等待获取锁标记。 当线程调用stop方法,即可使线程进入消亡状态,但是由于stop方法是不安全的,不鼓励使用,大家可以通过run方法里的条件变通实现线程的 stop。

  • 相关阅读:
    1063. Set Similarity
    A1047. Student List for Course
    A1039. Course List for Student
    最大公约数、素数、分数运算、超长整数计算总结
    A1024. Palindromic Number
    A1023. Have Fun with Numbers
    A1059. Prime Factors
    A1096. Consecutive Factors
    A1078. Hashing
    A1015. Reversible Primes
  • 原文地址:https://www.cnblogs.com/whyalwaysme/p/4495959.html
Copyright © 2011-2022 走看看