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

相关文章

来自专栏落花落雨不落叶

canvas画简单电路图

62011
来自专栏Ceph对象存储方案

Luminous版本PG 分布调优

Luminous版本开始新增的balancer模块在PG分布优化方面效果非常明显,操作也非常简便,强烈推荐各位在集群上线之前进行这一操作,能够极大的提升整个集群...

3145
来自专栏一个爱瞎折腾的程序猿

sqlserver使用存储过程跟踪SQL

USE [master] GO /****** Object: StoredProcedure [dbo].[sp_perfworkload_trace_s...

2060
来自专栏我和未来有约会

Kit 3D 更新

Kit3D is a 3D graphics engine written for Microsoft Silverlight. Kit3D was inita...

2536
来自专栏闻道于事

js登录滑动验证,不滑动无法登陆

js的判断这里是根据滑块的位置进行判断,应该是用一个flag判断 <%@ page language="java" contentType="text/html...

6828
来自专栏转载gongluck的CSDN博客

cocos2dx 打灰机

#include "GamePlane.h" #include "PlaneSprite.h" #include "BulletNode.h" #include...

5476
来自专栏Golang语言社区

【Golang语言社区】GO1.9 map并发安全测试

var m sync.Map //全局 func maintest() { // 第一个 YongHuomap := make(map[st...

4708
来自专栏我和未来有约会

Silverlight第三方控件专题

这里我收集整理了目前网上silverlight第三方控件的专题,若果有所遗漏请告知我一下。 名称 简介 截图 telerik 商 RadC...

4025
来自专栏java 成神之路

使用 NIO 实现 echo 服务器

4667
来自专栏大内老A

The .NET of Tomorrow

Ed Charbeneau(http://developer.telerik.com/featured/the-net-of-tomorrow/) Exciti...

31710

扫码关注云+社区