start()和run()方法对于刚接触线程的人来说,会有点混淆,有点难理解,一般都会有以下疑问:

一、start( )方法

1、为什么需要start方法;它的作用是什么;

start方法的作用就是将线程由NEW状态,变为RUNABLE状态。当线程创建成功时,线程处于NEW(新建)状态,如果你不调用start( )方法,那么线程永远处于NEW状态。调用start( )后,才会变为RUNABLE状态,线程才可以运行。

2、调用start()方法后,线程是不是马上执行?

线程不是马上执行的;准确来说,调用start( )方法后,线程的状态是“READY(就绪)”状态,而不是“RUNNING(运行中)”状态(关于线程的状态详细,可参考 java中的线程状态)。线程要等待CPU调度,不同的JVM有不同的调度算法,线程何时被调度是未知的。因此,start()方法的被调用顺序不能决定线程的执行顺序

注意一点:

由于在线程的生命周期中,线程的状态由NEW---》RUNABLE只会发生一次,因此,一个线程只能调用start()方法一次,多次启动一个线程是非法的。特别是当线程已经结束执行后,不能再重新启动。

二、run( )方法

1、run方法又是一个什么样的方法?run方法与start方法有什么关联?

run( )其实是一个普通方法,只不过当线程调用了start( )方法后,一旦线程被CPU调度,处于运行状态,那么线程才会去调用这个run()方法;

2、run()方法的执行是不是需要线程调用start()方法

上面说了,run()方法是一个普通的对象方法,因此,不需要线程调用start()后才可以调用的。可以线程对象可以随时随地调用run方法。

看一下下面的例子:

     Thread t1 = new Thread(new MyTask(1));
Thread t2 = new Thread(new MyTask(2));
t1.run();
t2.run();

上面的输出结果是固定的:

count的值:1

count的值:2

     Thread t1 = new Thread(new MyTask());
Thread t2 = new Thread(new MyTask());
t1.start();
t2.start();

这个输出结果不是固定的,因为线程的运行没法预测。运行结果可能不一样

MyTask 类:

//实现Runnable接口
class MyTask implements Runnable{ int count;
public MyTask(int count) {
this.count=count;
}
@Override
public void run() {
System.out.println("count的值:"+count);
}
}

三、要真正理解Thread类

Thread类的对象其实也是一个java对象,只不过每一个Thread类的对象对应着一个线程。Thread类的对象就是提供给用户用于操作线程、获取线程的信息。真正的底层线程用户是看不到的了。

因此,当一个线程结束了,死掉了,对应的Thread的对象仍能调用,除了start( )方法外的所有方法(死亡的线程不能再次启动),如run( )、getName( )、getPriority()等等

//简单起见,使用匿名内部类的方法来创建线程
Thread thread = new Thread(){
@Override
public void run() {
System.out.println("Thread对象的run方法被执行了");
}
};
//线程启动
thread.start(); //用循环去监听线程thread是否还活着,只有当线程thread已经结束了,才跳出循环
while(thread.isAlive()){}
//线程thread结束了,但仍能调用thread对象的大部分方法
System.out.println("线程"+thread.getName()+"的状态:"+thread.getState()+"---优先级:"+thread.getPriority());
//调用run方法
thread.run();
//当线程结束时,start方法不能调用,下面的方法将会抛出异常
thread.start();

运行结果:

<

并发基础(六) 线程Thread类的start()和run()的更多相关文章

  1. [深入学习C#]C#实现多线程的方法:线程(Thread类)和线程池(ThreadPool)

    简介 使用线程的主要原因:应用程序中一些操作需要消耗一定的时间,比如对文件.数据库.网络的访问等等,而我们不希望用户一直等待到操作结束,而是在此同时可以进行一些其他的操作.  这就可以使用线程来实现. ...

  2. C#实现多线程的方法:线程(Thread类)和线程池(ThreadPool)

    简介 使用线程的主要原因:应用程序中一些操作需要消耗一定的时间,比如对文件.数据库.网络的访问等等,而我们不希望用户一直等待到操作结束,而是在此同时可以进行一些其他的操作.  这就可以使用线程来实现. ...

  3. C#_02.15_基础六_.NET类

    C#_02.15_基础六_.NET类 一.类继承是一个类在另一个类的基础上进行的扩展. 继承的子类拥有父类的全部成员.索引子类拥有本身的全部成员以及父类的全部成员. 可以对基类成员进行隐藏,如果必须的 ...

  4. Python之路(第四十二篇)线程相关的其他方法、join()、Thread类的start()和run()方法的区别、守护线程

    一.线程相关的其他方法 Thread实例对象的方法 # isAlive(): 返回线程是否活动的. # getName(): 返回线程名. # setName(): 设置线程名. ​ threadin ...

  5. 并发基础篇(六):线程Thread类的start()方法和run()方法【转载】

    [转载] 一.初识java的线程是通过java.lang.Thread类来实现的.VM启动时会有一个由主方法所定义的线程.可以通过创建Thread的实例来创建新的线程.每个线程都是通过某个特定Thre ...

  6. JAVA与多线程开发(线程基础、继承Thread类来定义自己的线程、实现Runnable接口来解决单继承局限性、控制多线程程并发)

    实现线程并发有两种方式:1)继承Thread类:2)实现Runnable接口. 线程基础 1)程序.进程.线程:并行.并发. 2)线程生命周期:创建状态(new一个线程对象).就绪状态(调用该对象的s ...

  7. Java并发编程 (六) 线程安全策略

    个人博客网:https://wushaopei.github.io/    (你想要这里多有) 一.不可变对象-1 有一种安全的发布对象,即不可变对象. 1.不可变对象需要满足的条件 ① 对象创建以后 ...

  8. 【并发编程】关于Thread类的详细介绍

    多线程编程基础--Thread类 Thread类是Java中实现多线程编程的基础类.本篇博客就来介绍下Thread类的常用API和常见用法. Thread类常用的方法如下: Thread.active ...

  9. 线程 Thread类 的四个构造方法简介

    在线程中,Thread类有四个构造方法: 当我们使用 Thread类创建对象的时候,传入参数,就会用到构造方法.ThreadStart 和ParameterizedThreadStart 都是 委托类 ...

随机推荐

  1. c++  与  java  中的 继承

    C++ 代码: #include <iostream> #include <string> using namespace std; class Parent { public ...

  2. opencv-python教程学习系列1-安装库

    前言 以后的项目可能会用到python和opencv进行实现,故准备opencv-python教程学习系列记录学习过程的点滴,这是这一系列的开篇,坚持学习,共同进步. 系列教程参照OpenCV-Pyt ...

  3. JavaScript 之call , apply 和prototype 介绍

    1. 前言 为什么将这三个概念放在一起说.原因是这些是会在实现js 继承会需要使用到的 2. call 和 apply call 和 apply 的作用基本类似, 都是去执行function并将这个f ...

  4. 《DSP using MATLAB》Problem 3.7

    一个复数序列可以分解为共轭偶对称和共轭奇对称部分. 代码: %% ------------------------------------------------------------------- ...

  5. Linux(CentOS)搭建SVN服务器

    1.安装命令 yum -y install subversion 查看SVN安装位置 rpm -ql subversion 查看SVN版本 svnserve --version 2.创建版本库根目录( ...

  6. leetcode:Same Tree【Python版】

    1.p或q为None的情况用开始的两个if语句进行判断: 2.类中递归调用函数需要使用self进行调用: 3.代码很简洁,最后几行通过同时为None和同时非None的条件进行判断: # Definit ...

  7. j2ee使用struts实现用户的登陆及注冊

    用户名: 密码: <%-- 使用struts标签 --%> <%-- --%>

  8. BAT调用7z压缩程序

    @echo offset zip=C:\Program Files\7-Zip\7z.exeset timestamp=%date:~6,4%-%date:~0,2%-%date:~3,2%set d ...

  9. mysql 存储过程知识点

    一.创建存储过程 create procedure sp_name() begin ......... end 二.调用存储过程 1.基本语法:call sp_name(): 注意:存储过程名称后面必 ...

  10. Spring Cloud 入门 之 Hystrix 篇(四)

    原文地址:Spring Cloud 入门 之 Hystrix 篇(四) 博客地址:http://www.extlight.com 一.前言 在微服务应用中,服务存在一定的依赖关系,如果某个目标服务调用 ...