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 条评论
登录 后参与评论

相关文章

来自专栏鬼谷君

Linux三剑客之sed

1032
来自专栏加米谷大数据

MongoDB 概念解析

不管我们学习什么数据库都应该学习其中的基础概念,在mongodb中基本的概念是文档、集合、数据库,下面我们挨个介绍 下表将帮助您更容易理解Mongo中的一些概念...

34911
来自专栏老马说编程

(65) 线程的基本概念 / 计算机程序的思维逻辑

在之前的章节中,我们都是假设程序中只有一条执行流,程序从main方法的第一条语句逐条执行直到结束。从本节开始,我们讨论并发,在程序中创建线程来启动多条执行流,并...

2157
来自专栏博客园

Redis命令与配置

    slaveof  127.0.0.1 6379(设置Mater的Host以及Port)

1474
来自专栏noteless

-1-5 java 多线程 概念 进程 线程区别联系 java创建线程方式 线程组 线程池概念 线程安全 同步 同步代码块 Lock锁 sleep()和wait()方法的区别 为什么wait(),

java 多线程 概念 进程 线程区别联系 java创建线程方式 线程组 线程池概念 线程安全 同步 同步代码块 Lock锁  sleep()和wait()方法...

984
来自专栏MasiMaro 的技术博文

8086cpu中的标志寄存器与比较指令

在8086CPU中有一个特殊的寄存器——标志寄存器,该寄存器不同于其他寄存器,普通寄存器是用来存放数据的读取整个寄存器具有一定的含义,但是标志寄存器是每一位都有...

1051
来自专栏DannyHoo的专栏

block和代理

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/u010105969/article/details/...

1293
来自专栏salesforce零基础学习

salesforce lightning零基础学习(八) Aura Js 浅谈一: Component篇

我们在开发lightning的时候,常常会在controller.js中写 component.get('v.label'), component.set('v...

1042
来自专栏决胜机器学习

PHP开发过程的那些坑(二) ——PHP empty函数

PHP开发过程的那些坑(二)——PHP empty函数 (原创内容,转载请注明来源,谢谢) 坑: 在工作过程中,常用empty()函数判断数组是否为空,为空时返...

3688
来自专栏顶级程序员

你真的了解 volatile 关键字吗?

作者:Ruheng, www.jianshu.com/p/7798161d7472 一、Java内存模型 想要理解volatile为什么能确保可见性,就要先理...

3377

扫码关注云+社区