项目github地址:bitcarmanlee easy-algorithm-interview-and-practice
欢迎大家star,留言,一起学习进步

1.java中的线程状态

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

2.Thread中的start()方法与run()方法

java中的线程是通过java.lang.Thread类来实现的。JVM启动时会有一个由主方法所定义的线程,同时可以通过创建Thread的实例来创建新的线程。每个线程都是通过某个特定Thread对象所对应的方法run()来完成其操作的,方法run()称为线程体。通过调用Thread类的start()方法来启动一个线程。

看下jdk中的源码

   /*** If this thread was constructed using a separate* <code>Runnable</code> run object, then that* <code>Runnable</code> object's <code>run</code> method is called;* otherwise, this method does nothing and returns.* <p>* Subclasses of <code>Thread</code> should override this method.** @see     #start()* @see     #stop()* @see     #Thread(ThreadGroup, Runnable, String)*/@Overridepublic void run() {if (target != null) {target.run();}}

再参考一下start方法

   /*** Causes this thread to begin execution; the Java Virtual Machine* calls the <code>run</code> method of this thread.* <p>* The result is that two threads are running concurrently: the* current thread (which returns from the call to the* <code>start</code> method) and the other thread (which executes its* <code>run</code> method).* <p>* It is never legal to start a thread more than once.* In particular, a thread may not be restarted once it has completed* execution.** @exception  IllegalThreadStateException  if the thread was already*               started.* @see        #run()* @see        #stop()*/public synchronized void start() {/*** This method is not invoked for the main method thread or "system"* group threads created/set up by the VM. Any new functionality added* to this method in the future may have to also be added to the VM.** A zero status value corresponds to state "NEW".*/if (threadStatus != 0)throw new IllegalThreadStateException();/* Notify the group that this thread is about to be started* so that it can be added to the group's list of threads* and the group's unstarted count can be decremented. */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 thenit will be passed up the call stack */}}}

从源码以及当中的注释可以看出,run()其实是个普通方法,只不过当线程调用了start( )方法后,一旦线程被CPU调度,处于运行状态,那么线程才会去调用这个run()方法;
同时,run方法就是一个普通的方法,并不是需要调用start()方法以后才能调用run()方法,线程对象可以随时调用run()方法。

3.示例

public class ThreadDemo1 extends Thread {public ThreadDemo1() {this.setName("ThreadDemo1");}public static void printThreadInfo() {System.out.println("current thread name is: " + Thread.currentThread().getName());}@Overridepublic void run() {while (true) {printThreadInfo();try {Thread.sleep(100);} catch (Exception ex) {throw new RuntimeException(ex);}}}public static void main(String[] args) throws Exception {Thread t1 = new Thread(new Task(1));Thread t2 = new Thread(new Task(2));t1.start();t2.start();}
}
public class Task implements Runnable {int count;public Task(int count) {this.count = count;}@Overridepublic void run() {System.out.println("count is: " + count);}
}

上面的运行结果有可能是:

count is: 1
count is: 2

也有可能是

count is: 2
count is: 1

但是如果将

        t1.start();t2.start();

换成

        t1.run();t2.run();

那么结果一定是

count is: 1
count is: 2

再看另外一个示例,模拟两个线程运行。

public class ThreadDemo2 {public static void main(String[] args) {Thread t1 = new Thread(new C1());Thread t2 = new Thread(new C2());t1.start();t2.start();//t1.run();//t2.run();}
}class C1 implements Runnable {@Overridepublic void run() {try {for (int i = 0; i < 10; i++) {System.out.println(i);Thread.sleep(1000);}} catch (InterruptedException ex) {ex.printStackTrace();}}
}class C2 implements Runnable {public void run() {try {for (int j = 0; j > -10; j--) {System.out.println(j);Thread.sleep(1000);}} catch (InterruptedException ex) {ex.printStackTrace();}}
}

如果是调用start方法,输出为

0
0
1
-1
2
-2
-3
3
-4
4
-5
5
-6
6
7
-7
8
-8
9
-9

如果调用的是run方法,结果为

0
1
2
3
4
5
6
7
8
9
0
-1
-2
-3
-4
-5
-6
-7
-8
-9

4.简单小结

start方法是用于启动线程的,可以实现并发,而run方法只是一个普通方法,是不能实现并发的,只是在并发执行的时候会调用。

java线程系列一:Thread类中的start()方法与run方法相关推荐

  1. Java笔记-通过放射获取类中成员名及调用get方法及map构造JSON数据

    目录 通过反射获取类中成员名 通过反射调用get方法 map生成JSON数据 通过反射获取类中成员名 /*** 获取类中的所有成员名* @param currentClass* @return* @t ...

  2. Java多线程-线程的创建(Thread类的基本使用)

    文章目录 一. 线程和Thread类 1. 线程和Thread类 1.1 Thread类的构造方法 1.2 启用线程的相关方法 2. 创建第一个Java多线程程序 3. 使用Runnable对象创建线 ...

  3. 【转】java线程系列---Runnable和Thread的区别

    在java中可有两种方式实现多线程,一种是继承Thread类,一种是实现Runnable接口:Thread类是在java.lang包中定义的.一个类只要继承了Thread类同时覆写了本类中的run() ...

  4. java基础 通过继承Thread类和实现Runnable接口创建线程

    java 创建线程 Java中,线程也是一种对象,但不是任何对象都可以成为线程. 只有实现了Runnable接口或继承了Thread类的对象才能成为线程. 继承Thread类 //格式: class ...

  5. java 创建线程thread_初学Java多线程:用Thread类创建线程

    在Java中创建线程有两种方法:使用Thread类和使用Runnable接口.在使用Runnable接口时需要建立一个Thread实例.因此,无论是通过Thread类还是Runnable接口建立线程, ...

  6. java 继承thread_java线程-创建线程(继承 Thread 类)

    1.创建线程的方式 线程创建方式是:继承 Thread 类,重写 run 方法.如下:public class Task extends Thread{ @Override public void r ...

  7. 死磕 java线程系列之线程池深入解析——未来任务执行流程

    (手机横屏看源码更方便) 注:java源码分析部分如无特殊说明均基于 java8 版本. 注:线程池源码部分如无特殊说明均指ThreadPoolExecutor类. 简介 前面我们一起学习了线程池中普 ...

  8. java任务流程_死磕 java线程系列之线程池深入解析——普通任务执行流程

    (手机横屏看源码更方便) 注:java源码分析部分如无特殊说明均基于 java8 版本. 注:线程池源码部分如无特殊说明均指ThreadPoolExecutor类. 简介 前面我们一起学习了Java中 ...

  9. Java 线程 - 基础及工具类 (二)

    Java 并发系列文章 Java 线程 - 并发理论基础(一) Java 线程 - 基础及工具类 (二) Java 线程 - 并发设计模式 (三) Java 线程(二) 通用的线程生命周期 Java ...

  10. java线程开启不了_Java中多线程启动,为什么调用的是start方法,而不是run方法?...

    前言 大年初二,大家新年快乐,我又开始码字了.写这篇文章,源于在家和基友交流的时候,基友问到了,我猛然发现还真是这么回事,多线程启动调用的都是start,那么为什么没人掉用run呢?于是打开我的ide ...

最新文章

  1. c语言中的if语句_If ... C中的其他语句解释
  2. 什么是Python?前景怎么样?
  3. luvit 被忽视的lua 高性能框架(仿nodejs)
  4. python分几种_python有几种类型?
  5. 148. Sort List
  6. java拷贝文件权限_boto3 copy vs copy_object关于s3中的文件权限ACL
  7. unix命令的一般格式是_Linux tree 命令详细使用说明
  8. vc项目中加载多个lib遇到的问题
  9. linux添加怎么退出,linux – 是否可以设置’expect’的退出代码
  10. ADO.NET 快速入门(十五):ADO 应用转换为 ADO.NET
  11. 反编译用unity打包的资源文件
  12. 【docker系列】docker之部署springboot项目
  13. 计算仰角_41页最新全站仪测量方法及计算+图文解说,助你轻松掌握测量
  14. mysql数据库优化面试redis持久化_【大厂面试06期】谈一谈你对Redis持久化的理解?...
  15. lxterminal命令打开新窗口并执行python脚本
  16. windows关闭被占用的端口
  17. Word VBA-标题设置
  18. Android学生信息管理系统
  19. 微信小程序 | 模仿百思不得其姐
  20. c语言:(指针)实现输入三个整数从小到大排序

热门文章

  1. 设计模式学习与应用——单例模式
  2. pandas 修改 DataFrame 列名 1
  3. 绿色版Tomcat的配置
  4. 什么情况下使用多线程
  5. 对话CDN巨头Akamai:携手金山云,意欲何为?
  6. 赋能生态 变现为王——云市场生态变现之道
  7. spring cloud config-server 高可用配置中心
  8. 翻书插件:bookblock.js
  9. 有人很好奇我博客文章的默认展图是怎么弄的?
  10. 如何以最好的方式实现游戏关卡