转载请标明出处:
http://blog.csdn.net/hai_qing_xu_kong/article/details/70215452
本文出自:【顾林海的博客】

前言

一系列任务的同时运行称之为并发,可以认为是多个任务交替执行,并且多个任务之间有可能还是串行的,与并发相关的另一个概念是并行,并行是真正意义上的“同时执行”。

线程的两种创建方式

我们在Java中创建线程可以通过以下两种方式来创建:

  1. 继承Thread类,并且覆盖run()方法。
  2. 创建一个实现Runnable接口的类,使用带参数的Thread构造器来创建Thread对象。

接下来看看以下程序:

public class MyThread extends Thread{private int i;public MyThread(int i){this.i=i;}@Overridepublic void run() {System.out.println(Thread.currentThread().getName()+" : "+i);}}

创建了一个继承Thread类的MyThread子类,内部声明了一个名为i的私有int属性,通过构造器来初始化i的值,接着重写run方法,这个方法用来执行我们创建的线程的指令,在run()方法中输出当前线程名和i的值。下面是主类:

public class Client {public static void main(String[] args) {MyThread thread;for(int i=0;i<10;i++){thread=new MyThread(i);thread.setName("Thread "+i);thread.start();}}}

我们在主类中通过for循环创建了十个MyThread对象,并给这十个Thread对象设置名字。看看输出结果吧:

Thread 0 : 0
Thread 4 : 4
Thread 3 : 3
Thread 5 : 5
Thread 6 : 6
Thread 2 : 2
Thread 1 : 1
Thread 7 : 7
Thread 8 : 8
Thread 9 : 9

从输出结果来看,代码的运行结果与代码执行顺序或调用顺序是无关的。线程是一个子任务, CPU以不确定的方式,或者说是以随机时间来调用线程的run方法,所以会出现运行结果的顺序与执行顺序不一致的问题。

使用第二种方式实现Runnable接口来实现上面的代码:

public class MyRunnable implements Runnable{private int i;public MyRunnable(int i){this.i=i;}@Overridepublic void run() {System.out.println(Thread.currentThread().getName()+" : "+i);}}
public class Client {public static void main(String[] args) {for(int i=0;i<10;i++){MyRunnable runable=new MyRunnable(i);Thread thread=new Thread(runable);thread.setName("Thread "+i);thread.start();}}}

最后运行的结果与上面的一样,有可能输出顺序不同。

当然,我们在创建线程时也可以通过Thread类保存的一些属性来标示线程,比如通过getId()方法来获取线程的唯一标识符、通过getName()方法获取线程的名字、以及通过getPriority()方法获取线程的优先级。线程的优先级从1到10,其中1是最低优先级,10是最高优先级。

线程的状态

线程的状态可以通过getState()方法来获取,线程状态有6种:new、runnable、blocked、waiting、time waiting或者terminated。

new状态表示刚刚创建的线程,这种线程还没开始执行。当线程的start()方法被调用时,表示线程开始执行,这时处于runnable状态,如果线程在执行过程中遇到了synchronized同步块,就会进入blocked阻塞状态,这时线程就会暂停执行,直到获得请求的锁。waiting和time waiting都表示等待状态,区别是waiting会进入一个无时间限制的等待,time waiting会进行一个有时间的等待。当线程执行完毕,就会进入terminated状态,表示结束。下面我们用程序来模拟这几种状态。

public class MyRunnable implements Runnable{@Overridepublic void run() {System.out.println("Thread state : "+Thread.currentThread().getState());}}

创建实现Runnable接口的MyRunnable类,并在run方法中,输出当前线程的状态。

public class Client {public static void main(String[] args) {MyRunnable runable=new MyRunnable();Thread thread=new Thread(runable);System.out.println("Thread state : "+thread.getState());thread.start();}}

我们的主类先是创建MyRunnable对象,并以参数形式创建 Thread对象,随后在start之前获取线程状态。

我们看看输出结果:

Thread state : NEW
Thread state : RUNNABLE

很显然,在线程被构建时,但还没有调用start方法,时处于new状态,随后执行start方法,并在线程执行过程中输出该线程的状态为runnable状态。

下面是waiting和time waiting两种状态。

public class MyRunnable implements Runnable{@Overridepublic void run() {try {Thread.sleep(2000);} catch (InterruptedException e) {// TODO Auto-generated catch blocke.printStackTrace();}System.out.println("Thread state : "+Thread.currentThread().getState());}}

我们在run方法中通过Thread类的静态方法sleep睡眠2秒,随后输出该线程状态。

public class Client {public static void main(String[] args) {MyRunnable runable=new MyRunnable();Thread thread=new Thread(runable);thread.start();try {Thread.sleep(1000);System.out.println("Thread state : "+thread.getState());} catch (InterruptedException e) {// TODO Auto-generated catch blocke.printStackTrace();}}}

在主类中,创建Thread对象,并启动线程,接着睡眠1秒后输出,thread对象的状态,当睡眠一秒后,thread对象还是处于睡眠状态,由此输出结果:

Thread state : TIMED_WAITING
Thread state : RUNNABLE

线程进入等待状态,进入该状态表示当前线程需要等待其他线程做出一些特定动作(通知或中断)。

我们在上面的主类中多加一段代码:

public class Client {public static void main(String[] args) {MyRunnable runable=new MyRunnable();Thread thread=new Thread(runable);thread.start();try {Thread.sleep(1000);System.out.println("Thread state : "+thread.getState());} catch (InterruptedException e) {// TODO Auto-generated catch blocke.printStackTrace();}try {Thread.sleep(3000);System.out.println("Thread state : "+thread.getState());} catch (InterruptedException e) {// TODO Auto-generated catch blocke.printStackTrace();}}}

在休眠3秒后输出thread对象的状态,这时创建的线程已经执行完毕,我们可以通过运行结果来查看:

Thread state : TIMED_WAITING
Thread state : RUNNABLE
Thread state : TERMINATED

阻塞状态,表示线程阻塞于锁:

public class MyRunnable implements Runnable{@Overridepublic void run() {synchronized (MyRunnable.class) {try {Thread.sleep(3000);System.out.println(Thread.currentThread().getName()+" state : "+Thread.currentThread().getState());} catch (InterruptedException e) {// TODO Auto-generated catch blocke.printStackTrace();}}}}

创建实现Runnable接口的类,并实现run方法,在run方法中通过synchronized同步这段代码块。

public class Client {public static void main(String[] args) {MyRunnable runable=new MyRunnable();Thread thread1=new Thread(runable,"Thread-1");Thread thread2=new Thread(runable,"Thread-2");thread1.start();thread2.start();try {thread1.sleep(1000);System.out.println(thread2.getName()+" state :"+thread2.getState());} catch (InterruptedException e) {// TODO Auto-generated catch blocke.printStackTrace();}}}

在主类中创建了两个Thread对象,当两个线程执行start方法后,睡眠1秒,输出thread2的状态,这时,thread1睡眠3秒才会释放锁,因此,thread2因为同步机制被挂起,直到thread1线程离开synchronized同步块(临界区)。运行结果:

Thread-2 state :BLOCKED
Thread-1 state : RUNNABLE
Thread-2 state : RUNNABLE

有关线程的相关知识(上)相关推荐

  1. 有关线程的相关知识(下)

    转载请标明出处: http://blog.csdn.net/hai_qing_xu_kong/article/details/70339618 本文出自:[顾林海的博客] 前言 在上一篇文章<有 ...

  2. java线程知识梳理_Java多线程——多线程相关知识的逻辑关系梳理

    1 学习多线程知识的根本目标 多线程知识的根本目标是:设计稳健的并发程序. 当然,本文无法回答这个实践性很强的问题(这与具体的业务相关,涉及到具体的策略),本文主要阐述相关知识之间的关系,希望初学者不 ...

  3. terminated 线程_深入并发,线程相关知识全解析

    一.前言 本文介绍Java线程相关知识(不包括线程同步+线程通信,这个内容在笔者的另一篇博客中介绍过了),包括:线程生命周期.线程优先级.线程礼让.后台线程.联合线程. 二.线程生命周期 2.1 引子 ...

  4. 使用Nginx+uwsgi在亚马逊云服务器上部署python+django项目完整版(二)——部署配置及相关知识...

    ---恢复内容开始--- 一.前提: 1.django项目文件已放置在云服务器上,配置好运行环境,可正常运行 2.云服务器可正常连接 二.相关知识 1.python manage.py runserv ...

  5. 关于外贸的相关知识和经验(上)

    相信许多从事外贸行业的人都已经掌握了很多关于外贸干货的知识累积,例如可以用WhatsApp.intbell和客户保持持续的沟通和联系,可以用google map 寻找客户等等.但很多时候我们积累了很多 ...

  6. 面试官:Java如何绑定线程到指定CPU上执行?

    不知道你是啥感觉,但是我第一次看到这个问题的时候,我是懵逼的. 而且它还是一个面试题. 我懵逼倒不是因为我不知道答案,而是恰好我之前在非常机缘巧合的情况下知道了答案. 我感觉非常的冷门,作为一个考察候 ...

  7. 【提高系列】webpack相关知识

    这次我们主要研究的是webpack框架的相关知识,webpack是一个打包构建的前端框架,用于解决前端开发的模块化问题. 应用场景和纵向比较 说到webpack,肯定你还会想到gulp和grunt这些 ...

  8. Redis面试题相关知识整理

    Redis面试题相关知识整理 1.Redis的应用场景 2.Redis的特点 3.Redis对各种数据类型的操作 4.Redis的持久化机制 5.Redis的缓存穿透/缓存击穿/缓存雪崩问题 6.Re ...

  9. 后端技术:消息队列MQ/JMS/Kafka相关知识介绍

    ?今天给大家分享消息队列MQ/JMS/Kafka相关知识介绍 1.消息队列介绍 首先举个收快递的栗子,传统的收快递,快递小哥把我们的快递送到我们的手里.他需要什么条件嗯? 快递小哥有时间送, 我们有时 ...

最新文章

  1. 详解阿里开源分布式事务框架Seata
  2. 推荐系统--基于用户的协同过滤算法
  3. 二级list列表python_Python 基本语法(二) —— 列表 (list)
  4. 天翼云从业认证(2.1)云计算的定义、特点、背景和发展历程
  5. Marshal类的简单使用
  6. 使用mysqlbinlog恢复指定表
  7. 前端学习(587):快速调试css数值及颜色图形动画
  8. android小细节
  9. 《深入理解分布式事务》第九章 可靠消息最终一致性分布式事务原理
  10. 不同vlan同段IP通信
  11. Java实现在线语音识别
  12. Linux登录日志配置,Unix系统用户登录及操作命令日志配置的方法
  13. 第一次冲刺-站立会议02
  14. [Ubuntu] 安装字体
  15. 雷达相关书籍学习顺序推荐
  16. 如何用MATLAB加速,使用MATLAB加速C/C++算法开发
  17. 正确握笔姿势~超详细完整重点解说图
  18. The scripts f2py, f2py3 and f2py3.8 are installed in ‘/home/cyd/.local/bin‘ which is not on PATH
  19. 无线通信与生活-(1)
  20. 如何让音乐软件的歌词在touch bar上面显示?

热门文章

  1. oracle 06502 解决,ora-06502如何解决。。。
  2. mysql distinct多个字段_深入浅出Mysql索引的那些事儿
  3. centos代码切换图形_沙迪克慢走丝代码大全,G代码、T代码、M代码(值得收藏)...
  4. linux中python如何调用matlab的数据_?如何在Python中加入多个数据帧?
  5. Kubernetes(1) kubectl 入门
  6. [JavaScript]只需一行代码,轻松搞定快捷留言-V2升级版
  7. JVM是怎么工作的?
  8. mysql忘记密码怎么改
  9. 2018/12/08 L1-045 宇宙无敌大招呼 java
  10. [转载zz] Python3 输入和输出之序列化与反序列化