启动一个线程是用run()还是start()

  启动线程肯定要用start()方法。当用start()开始一个线程后,线程就进入就绪状态,使线程所代表的虚拟处理机处于可运行状态,这意味着它可以由JVM调度并执行。这并不意味着线程就会立即运行。当cpu分配给它时间时,才开始执行run()方法(如果有的话)。start()是方法,它调用run()方法。而run()方法是你必须重写的. run()方法中包含的是线程的主体。

继承Thread类的启动方式:

1 public class ThreadStartTest {
2     public static void main(String[] args) {
3         ThreadTest tt = new ThreadTest();// 创建一个线程实例
4          tt.start();  // 启动线程
5     }
6 } 

实现Runnable接口的启动方式:

1 public class RunnableStartTest {
2     public static void main(String[] args) {
3        Thread t = new Thread(new RunnableTest());    // 创建一个线程实例
4         t.start();  // 启动线程
5     }
6 }

实际上这两种启动线程的方式原理是一样的。首先都是调用本地方法启动一个线程,其次是在这个线程里执行目标对象的run()方法。那么这个目标对象是什么呢?为了弄明白这个问题,我们来看看Thread类的run()方法的实现:

1 public void run() {
2     if (target != null) {
3         target.run();
4     }
5 } 

  当我们采用实现Runnable接口的方式来实现线程的情况下,在调用new Thread(Runnable target)构造器时,将实现Runnable接口的类的实例设置成了线程要执行的主体所属的目标对象target,当线程启动时,这个实例的 run()方法就被执行了。当我们采用继承Thread的方式实现线程时,线程的这个run()方法被重写了,所以当线程启动时,执行的是这个对象自身的 run()方法。总结起来就一句话,如果我们采用的是继承Thread类的方式,那么这个target就是线程对象自身,如果我们采用的是实现Runnable接口的方式,那么这个target就是实现了Runnable接口的类的实例。

原文链接:https://blog.csdn.net/xieping1990/article/details/6433046

原文地址:https://www.cnblogs.com/116970u/p/11508812.html

时间: 2024-11-07 12:15:01

启动一个线程是用run()还是start()的相关文章

如何定义,创建,启动一个线程

如何定义一个线程?第一通过继承java.lang.Thead类来定义一个线程.第二,通过实现java.lang.runnable接口定义一个线程. 为什么不采用run方法直接启动线程呢?线程是由操作系统来管理的,操作系统启动一个线程,会调用本地的一个代码,这个本地的代码会使系统初始化一个新的线程,由新的线程来启动Thead类中的run方法,所以要通过start方法来启动一个线程 两种定义线程的方式都有哪些优缺点?

随着tomcat一起启动一个线程 (转)

原帖:http://blog.163.com/[email protected]/blog/static/1806962120124285346297/ 在Java web开发时如何在开启一个后台线程,随着Tomcat的启动而执行呢? 可以参考下面的步骤: 1.首先在工程中定义Class继承ServletContextListener接口,并定义线程和线程函数,实例如下代码: package test; import javax.servlet.*; public class MyCode im

如何创建和启动一个线程?

原文转自:http://www.tqcto.com/article/recommend/137.html 一.定义线程 1.继承java.lang.Thread类. 此类中有个run()方法,应该注意其用法: public void run() 如果该线程是使用独立的 Runnable 运行对象构造的,则调用该 Runnable 对象的 run 方法:否则,该方法不执行任何操作并返回. Thread 的子类应该重写该方法. 2.实现java.lang.Runnable接口. public  vo

JAVA线程池原理源码解析—为什么启动一个线程池,提交一个任务后,Main方法不会退出?

起因 public static void main(String[] args) { ExecutorService service = Executors.newFixedThreadPool(10); service.submit(() -> System.out.println("Hello ")); System.out.println("World"); } 呵呵,执行结果谁都知道,显而易见结论线程池的创建的时候,第一次submit操作会创建Wor

当多个客户请求一个servlet时,引擎为每个客户启动一个线程,那么servlet类的成员变量被所有的线程共享?

因为servlet的实现是单例,多线程也就是说,N个客户端请求同一个servlet,他们所请求的是同一个对象,成员变量是属于这个对象的,因此成员变量也被共享了因此在servlet编程中,无状态的servlet(就是不写属性,所以变量都在dopost或者doget里面)是线程安全的,否则,由于会共享到成员变量,因此就有可能不是线程安全的.

由一个成员函数来启动一个线程

/*shows how to start a thread based on a class memeber function using a static member function.*/ #define WIN32_LEAN_AND_MEAN #include<stdio.h> #include<stdlib.h> #include<Windows.h> #include<process.h> typedef unsigned(WINAPI *PBE

线程start() 和run()的区别

一个面试题引发的思考: 一个线程上直接调用了run()方法结果如何?我当时想的是抱方法找不到错误,今天测试了一下我错了!找了点资料学习了下,加上自己的理解整理如下(望指点). (1)调用start: 调用start()启动一个线程,该线程进入就绪状态,等待cpu分配执行时间,一旦得到执行时间就执行 run()线程体.无需等待该线程执行完毕再执行其他线程,真正实现多线程,cpu不会因为某个线程需要等待资源而进入空闲状态,cpu会被分配给其他线程执行. 测试代码: ? 1 2 3 4 5 6 7 8

从Thread.start()方法看Thread源码,多次start一个线程会怎么样

这篇文章作为Thread类源码剖析的补充,从一个侧面来看Thread源码.也解答了面试高频问题:"多次start一个线程会怎么样?" 答案是:java.lang.IllegalThreadStateException   线程状态非法异常   继承关系是:--->extends IllegalArgumentException--->extends RuntimeException一个运行时异常,下面我们从源码来透彻分析一下start()时做了什么. 1 /** 2 * C

JAVA基础----应用程序中如何新开一个线程

通过继承Thread新开线程 将类声明为 Thread 的子类.该子类应重写 Thread 类的 run 方法.接下来可以分配并启动该子类的实例.例如,计算大于某一规定值的质数的线程可以写成: class PrimeThread extends Thread { long minPrime; PrimeThread(long minPrime) { this.minPrime = minPrime; } public void run() { // compute primes larger t