java线程的start方法_Java线程中的run和start方法

刚开始接触线程的时候,只是生硬的记住了如果要启动一个线程必须调用该线程的start方法,可是由于刚开始不经常使用多线程方面的知识,所以渐渐的就模糊了,现在常常碰到多线程的使用,知其然知其所以然嘛,今天就从源码方面探究一下。

run方法

查看一下JDK的源码,可以看到Thread中的run方法调用的是Runnable中run:

private Runnable target;

public void run() {

if (target != null) {

target.run();

}

}

Thread中定义了一个Runnable类型的私有属性target,在不为空的情况下直接调用了Runnable的run方法,接着看Runnable源码:

public interface Runnable {

public abstract void run();

}

Runnable接口中就一个方法,一直感觉线程是非常高大上的东西,为什么到了这里会这么简单呢,大概越抽象的东西越不容易错吧,所以领导人说话向来都很抽象,呵呵。到这里大概有些恍然大悟了,怪不得两种创建线程的方式都需要实现run方法呢,很简答的一个接口回调,差不多就是这个意思。所以如果我们创建线程之后如果直接调用该线程的run方法,就跟执行其它方法一样,在主线程中顺序执行,并没有达到多线程的效果。

下面写一个简单的demo来测试一下

private class RunTask extends Thread {

public RunTask(String name) {

super(name);

}

public void run() {

System.out.println("sub:"+Thread.currentThread().getId());

System.out.println("======" + this.getName());

}

}

public void m1() {

Thread demo01 = new RunTask("demo01");

Thread demo02 = new RunTask("demo02");

demo01.run();

demo02.run();

}

下面是主方法,在控制台可以看到输出结果

public static void main(String[] args) {

MainTest main = new MainTest();

System.out.println("main:"+Thread.currentThread().getId());

main.m1();

}

//输出结果如下

//main:1

//sub:1

//======demo01

//sub:1

//======demo02

无论我们运行多少次,demo01和demo02一定是顺序执行的,并且它们的线程ID始终是相同的,这说明直接调用run方法并没有开启一个线程,只是执行了普通的方法调用。

start方法

既然前面直接调用run方法没有开启新的线程,start方法到底做了哪些工作呢,同样在Thread源码中找到start源码:

public synchronized void start() {

if (threadStatus != 0)

throw new IllegalThreadStateException();

group.add(this);

start0();

if (stopBeforeStart) {

stop0(throwableFromStop);

}

}

private native void start0();

start方法调用了一个本地方法start0,本地方法调用就深入到了更底层的调用了,从这里我们就可以知道事实上是在底层开启了一个新的线程,写个简单的demo看一下效果,RunTask还是使用上面的代码

public void m2() {

Thread demo01 = new RunTask("demo01");

Thread demo02 = new RunTask("demo02");

demo01.start();

demo02.start();

}

// main方法

public static void main(String[] args) {

MainTest main = new MainTest();

System.out.println("main:" + Thread.currentThread().getId());

main.m2();

}

//程序执行结果

//main:1

//sub:9

//======demo02

//sub:8

//======demo01

如果多运行几次,我们会发现demo01和demo02并不是按顺序执行的,而且线程的ID已经与main线程的明显不同的。

还有一点就是start方法只能执行一次,如果我们在执行一次就会抛出IllegalThreadStateException异常,从上面摘出来的start方法中我们知道,Thread中有一个int类型的标识threadStatus,只要它不等于0就会抛出异常,JDK中对threadStatus的说明:

Java thread status for tools,

initialized to indicate thread 'not yet started'

简单翻译一下就是线程状态标识,初始值来标记线程还没有开始。所以当我们调用一次start方法之后threadStatus的值就发生了变化,所以如果在调用start方法就抛出异常。

关于run和start方法的简单介绍就这么多吧,限于个人能力有限文章难免有错误疏忽之处还请多多指教。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值