谈谈对java线程的理解(一)--------线程的创建与启动

最近温习了下线程的相关知识点,在这里和大家分享下。

刚开始接触java的伙伴,可能对线程什么的比较迷糊,茫茫然死记硬背了一点,其中的知识总是感觉晕晕乎乎,好像懂了又好像没懂。

想要理解java线程的知识点,首先要明白进程与线程的含义,下面是摘抄的线程与进程的说明。

进程是程序的一次执行过程,是系统运行程序的基本单位,因此进程是动态的。系统运行一个程序即是一个进程从创建,运行到消亡的过程。

线程与进程相似,但线程是一个比进程更小的执行单位。一个进程在其执行的过程中可以产生多个线程。与进程不同的是同类的多个线程共享进程的方法区资源,但每个线程有自己的程序计数器虚拟机栈本地方法栈,所以系统在产生一个线程,或是在各个线程之间作切换工作时,负担要比进程小得多,也正因为如此,线程也被称为轻量级进程。

用java中一直在用的虚拟机来说,你启动一个main()方法,就是启动了一个JVM进程,而这个进程中包含守护线程(垃圾回收)与普通的线程(main方法中之行的任务)

刚开始接触java线程,我们知道java线程两种常见的创建方式,继承Thread与实现Runnable。如果你不明白的话,那就提前先死记住吧,这个java语言就是这么规定的,没啥好说的,接触久了自然就习惯了。

下面实现写两个简单的线程:

继承Thread

package com.example.demoproject;

public class ThreadEx extends Thread{


    public ThreadEx(String name) {
        super(name);
    }

    /**
     * 重写run()方法
     */
    @Override
    public void run() {
        System.out.println("运行方式"+this.getName()+"  ThreadEx方法名称:"+Thread.currentThread().getName()+"  Thread id信息:"+Thread.currentThread().getId());
    }
}

实现Runable方法

package com.example.demoproject;

public class ThreadRun implements Runnable {

    private String name;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public ThreadRun(String name) {
        this.name = name;
    }

    @Override
    public void run() {
        System.out.println("ThreadRun方法名称:"+Thread.currentThread().getName()+" Thread id信息:"+Thread.currentThread().getId());
    }
}

接触线程创建之后,我们知道线程有两种启动方式:start()与run(),那这两种方式有什么区别呢?我们来运行下程序看看。

package com.example.demoproject;

public class ThreadTest {

    public static void main(String[] args) {

        ThreadRun runThread = new ThreadRun("runThread");
        ThreadEx threadEx1 = new ThreadEx("start");
        ThreadEx threadEx2 = new ThreadEx("run");

        runThread.run();

        threadEx1.start();
        threadEx2.run();
    }
}

程序运行结果:

ThreadRun方法名称:main Thread id信息:1
运行方式run  ThreadEx方法名称:main  Thread id信息:1
运行方式start  ThreadEx方法名称:start  Thread id信息:11

Process finished with exit code 0

大家可以看到总共有两个线程,线程的id分别是1和11,runThread实现了run()方法,不过是没有start()方法的哟。

我们可以看到,main()方法的线程id是1,使用run()方法启动的两个线程,线程的id也是1,。这说明了什么?使用run()方法并没有新建线程!

而是用start()方法启动的线程,线程id是11,和main()不是同一个线程,很明显是启动了一个新的线程。

所以,使用run()方法运行线程,就是相当于创建了一个对象,然后调用了对象的一个方法,并没有创建线程的操作,只有使用start()启动的时候才会新建线程。

当然,现实编码中很少去自己创建线程的,因为频繁的创建和销毁线程对服务来说也是不小的开销。我们一般调用线程池中的线程为我们服务。

对了,大家看下运行结果,有没有感觉什么不对的地方?

比如:我代码里明明是先写的start()方法,可运行的时候怎么start()方法在最后了?为什么不是按顺序来呢?大家可以试下,发现大部分情况都是和我的运行结果一致。

这里来说的话,首先,start()方法会重建一个线程,这个操作无疑是会耗时的,但是这个并不影响main()方法的运行,所以等新线程创建完毕,main()方法已经运行到下面的代码了,start()方法之行自然会显得慢一些。

No sacrifice, no victory!

猜你喜欢

转载自blog.csdn.net/zsah2011/article/details/107238233
今日推荐