java多线程——线程的状态

线程的状态转换如下图所示:

可以参考我的另一篇博客线程状态转换的内容。

线程的创建

实现Runnable接口

这个接口非常简单:

@FunctionalInterface
public interface Runnable {
    /**
     * When an object implementing interface <code>Runnable</code> is used
     * to create a thread, starting the thread causes the object's
     * <code>run</code> method to be called in that separately executing
     * thread.
     * <p>
     * The general contract of the method <code>run</code> is that it may
     * take any action whatsoever.
     *
     * @see     java.lang.Thread#run()
     */
    public abstract void run();
}

注释写的很清楚,这个接口用于创建一个线程,当一个类实现了这个接口,就会导致重写的run方法被调用,可以在run方法里实现自己的业务逻辑。可以如下所示实现一个类。

public class myRunnable implements Runnable{

    @Override
    public void run() {
        //task code
    }
}

然后

public class Main {
    public void main(String[] args){
        //创建一个类对象
        Runnable runnable = new myRunnable();
        //由Runnable创建一个Thread对象
        Thread thread = new Thread(runnable);
        //启动线程
        thread.start();
    }
}

构建Thread类的子类

也可以通过构建Thread类的子类来定义一个线程。

public class myThread extends Thread {
    public void run(){
        //task code
    }
}

然后,构建一个子类的对象,并调用start方法。不过,这种方法已经不再推荐。应该从运行机制上减少需要并行运行的任务数量。如果有很多任务,要为每个任务创建一个独立的线程所付出的代价太大了。可以使用线程池解决这个问题。

注意

不要调用Thread类或者Runnable对象的run方法,直接调用此方法,只会执行同一个线程中的任务,而不会启动新线程。应该调用thread.start方法。这个方法将创建一个执行run方法的新线程。

线程的中断

当线程的run方法执行方法体的最后一条语句并由执行return语句返回时,或者出现了在方法中没有捕捉的异常时,线程将终止。

interrupt方法

该方法用来请求终止线程,注意,是请求,不是强制。 当对一个线程调用此方法时,线程的中断状态将会被置位。这时每一个线程都具有的boolean标志,每个线程都应该时不时的检查这个标志,以判断线程是否被中断。 使用下面的方法判断当前线程是否被中断:

while(!Thread.currentThread().isInterrupted()&&more work to do){
    //do something
}

如果一个线程被阻塞,就无法检测中断状态,就会产生InterruptedException异常。当一个被阻塞的线程(如调用sleep或wait)上调用interrupt方法时,阻塞调用会被interred Exception异常中断。 值得注意的是,被中断的线程可以决定如何响应中断,一些重要的线程会在处理完异常后继续执行而不理会中断。一般情况下,线程简单的将中断作为一个终止的请求,如下所示:

public void run() {
        try {
            ......
            while (!Thread.currentThread().isInterrupted())&&more work to do){
                //do something
            }
        }catch (InterruptedException e){
            //thread was interruped during sleep or wait
        }finally {
            //clean up,if required
        }
    }

如果每次工作迭代之后都调用sleep方法,isInterrupted检测既没有必要也没有用处。如果在中断状态被置位时调用sleep方法,线程不会休眠反而会清除这一状态并且抛出中断异常。因此,如果你的循环调用sleep,不会检测中断状态,相反,需要捕获中断异常。

interrupted和isInterrupted的区别

interrupted是一个静态方法,会检测当前的线程是否被中断,而且,调用此方法会清除掉该线程的中断状态。 isInterrupted方法是一个实例方法,可用于检测是否有线程被中断,并不会改变中断状态。

多任务与多线程的区别

多任务(multitasking):在同一刻运行多个程序的能力。 多线程(multithreaded):一个程序同时执行多个任务,可以同时执行一个以上线程的程序称为多线程程序。 多进程与多线程的本质区别在于:每个进程拥有自己的一整套变量,而线程则共享数据。共享变量使得线程之间的通信比进程之间更加有效及容易。

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏Java面试笔试题

什么是线程池(thread pool)?

在面向对象编程中,创建和销毁对象是很费时间的,因为创建一个对象要获取内存资源或者其它更多资源。在Java中更是如此,虚拟机将试图跟踪每一个对象,以便能够在对象销...

822
来自专栏好好学java的技术栈

「附数据结构资源」玩转java并发(六):深入线程Thread类的start()方法和run()方法

java的线程是通过java.lang.Thread类来实现的。VM启动时会有一个由主方法所定义的线程。可以通过创建Thread的实例来创建新的线程。每个线程都...

892
来自专栏大数据架构

Java进阶(四)线程间通信剖析

1794
来自专栏菩提树下的杨过

java:多线程基础之Runnable、Callable与Thread

java.lang包下有二个非常有用的东西:Runnable接口与Thread类,Thread实现了Runnable接口(可以认为Thread是Runnable...

19410
来自专栏xingoo, 一个梦想做发明家的程序员

Java多线程之Runable与Thread

Java多线程是Java开发中的基础内容,但是涉及到高并发就有很深的研究可做了。 最近看了下《Java并发实战》,发先有些地方,虽然可以理解,但是自己在应用...

2029
来自专栏高爽的专栏

Java线程(四):线程中断、线程让步、线程睡眠、线程合并

最近在Review线程专栏,修改了诸多之前描述不够严谨的地方,凡是带有Review标记的文章都是修改过了。本篇文章是插进来的,因为原来没有写,现在...

2200
来自专栏好好学java的技术栈

深入线程Thread类的start()方法和run()方法

java的线程是通过java.lang.Thread类来实现的。VM启动时会有一个由主方法所定义的线程。可以通过创建Thread的实例来创建新的线程。每个线程都...

580
来自专栏青枫的专栏

java基础学习_多线程01_多线程_day23总结

582
来自专栏Java 源码分析

Exectors框架 源码分析

Exectors框架 源码分析 1. 在阅读源码时做了大量的注释,并且做了一些测试分析源码内的执行流程,由于博客篇幅有限,并且代码阅读起来没有 IDE 方便,...

2546
来自专栏Java 源码分析

NioEventLoopGroup 源码分析

NioEventLoopGroup 源码分析 1. 在阅读源码时做了一定的注释,并且做了一些测试分析源码内的执行流程,由于博客篇幅有限。为了方便 IDE 查看...

3256

扫码关注云+社区