操作系统中的进程和线程的概念

进程是指一个内存运行的应用程序,每个进程都有自己独立的一块内存空间,一个进程中可以启动多个线程,比如windows下的一个运行的应用程序.exe就是一个进程。

线程是指进程中的一个执行流,一个进程可以运行多个线程。如java.exe就可以运行很多个线程。线程总是属于某个进程,进程中的多个线程共享进程中的内存。

操作系统中可以同时执行多个任务,每个任务就是进程;进程可以同时执行多个任务,每个任务就是线程。

线程的状态

1、新建(new):线程对象被创建后就进入了新建状态。如:Thread thread = new Thread();

2、就绪状态(Runnable):也被称为“可执行状态”。线程对象被创建后,其他线程调用了该对象的start()方法,从而启动该线程。如:thread.start(); 处于就绪状态的线程随时可能被CPU调度执行。

3、运行状态(Running):线程获取CPU权限进行执行。需要注意的是,线程只能从就绪状态进入到运行状态。

4、阻塞状态(Blocked):阻塞状态是线程因为某种原因放弃CPU使用权限,暂时停止运行。直到线程进入就绪状态,才有机会进入运行状态。阻塞的三种情况:

1)等待阻塞:通过调用线程的wait()方法,让线程等待某工作的完成。

2)同步阻塞:线程在获取synchronized同步锁失败(因为锁被其他线程占用),它会进入同步阻塞状态。

3)其他阻塞:通过调用线程的sleep()或join()或发出了I/O请求时,线程会进入到阻塞状态。当sleep()状态超时、join()等待线程终止或超时、或者I/O处理完毕时,线程重新转入就绪状态。

5、死亡状态(Dead):线程执行完了或因异常退出了run()方法,该线程结束生命周期。

常用的实现多线程的方式

1、继承Thread类publicclassThread implementsRunnable {、、、、、}

由Thread的源码可以看出,Thread是实现了Runnable接口。

2、实现Runnable接口

publicinterfaceRunnable {

public abstract voidrun();}

Runnable接口只有一个run()方法

————————————————————————————————————————————————

Thread和Runnable都是是实现实现多线程的方式。不同的是Thread是类,Runnable是接口——Thread本身实现了Runnable接口,一个类只能有一个父类,但是却可以是实现多个接口,因此Runnable具有更好的扩展性。

Thread实现多线程public classMyThread extendsThread {

private inti;@Override/** 重写run方法*/public voidrun(){

for(inti = 0;i < 50;i++) {

/*** 当继承Thread类可以直接用this获取当前线程* 用getName()获取当前线程的名字*/System.out.println(this.getName()+"-"+i);}

}

public static voidmain(String[] args) {

for(inti = 0;i < 100;i++) {

//通过Thread.currentThread()获取当前线程System.out.println(Thread.currentThread().getName()+" "+i);if(i==20){

//创建并启动第一个线程newMyThread().start();//创建并启动第二个线程newMyThread().start();}

}

}

}

Runnable实现多线程public classMyRunnable implementsRunnable {

private inti;@Overridepublic voidrun() {

for(inti = 0;i < 50;i++) {

/**当线程类实现Runnable接口的时候,获取当前线程只能用Thread.currentThread()*/System.out.println(Thread.currentThread().getName()+" "+i);}

}

public static voidmain(String[] args) {

for(inti = 0;i < 100;i++) {

// System.out.println(Thread.currentThread().getName()+" "+i);if(i==20){

MyRunnable mr = newMyRunnable();//通过new Start()方法创建新线程newThread(mr,"线程1").start();newThread(mr,"线程2").start();}

}

}

}

关于线程中的start()和run()

启动线程使用start(),而不是run()!

在执行start()方法之前,只是有一个Thread对象,还没一个真正的线程。(分配内存,初始化成员变量)

——>start()之后,线程状态从新状态到可执行状态。(调用栈和计数器,线程没运行,只是可以运行)

——>当线程获得执行机会时,其目标run()方法将运行。

start():他的作用是启动一个新线程,新线程会调用相应的run()方法。start()不能被重复调用。

run():和普通成员的方法一样可以被重复调用。单独调用run()会在当前线程中执行run(),而不会启动新的线程。

public classMyThread extendsThread {@Override/** 重写run方法*/public voidrun(){

}

}

MyThread myThread = new MyThread();

如:myThread.start()会启动一个新的线程,然后在新线程中执行run()方法。

myThread.run()会直接在当前线程中运行run()方法,不会启动一个线程。

start方法源码:public synchronized voidstart() {

/**

*如果线程不是就绪状态就抛出异常*/if(threadStatus!= 0)

throw newIllegalThreadStateException();/* 将线程添加到group当中 */group.add(this);booleanstarted = false;try{

start0();//通过start0启动线程started = true;//设置started标记} finally{

try{

if(!started) {

group.threadStartFailed(this);}

} catch(Throwable ignore) {

/* do nothing. If start0 threw a Throwable thenit will be passed up the call stack */}

}

}

run方法源码:public voidrun() {

if(target!= null) {

target.run();}

}

其中target是Runnable对象, 直接调用Thread线程中Runnable接口中run方法,不会新建一个线程。

当线程获得CPU,开始执行run()方法的线程执行体,则该线程处于运行状态。

关于阻塞

进入阻塞的情况:解除上面阻塞情况:

1、线程调用sleep()方法主动释放占用的处理器资源

2、调用了一个阻塞式的IO方法,在方法返回前线程被阻塞

3、线程获得了一个同步监视器(Syschronized),但该监视器正被其他线程持有

4、线程在等待某个通知(notify)

5、程序调用了线程的resume()方法将线程挂起。但是该方法容易发生死锁,所以尽量避免使用1、调用sleep()方法经过了指定的时间

2、线程调用的IO阻塞方法已经返回

3、线程成功的获得了试图取得的同步监视器

4、线程正在等待某个通知时,其他线程发出了一个通知

5、处于挂起的线程被调用了resume()恢复方法。

线程从阻塞状态只能进入就绪状态,无法进入运行状态,而从就绪到运行不受程序控制,由系统线程调度决定。

获得资源进入运行状态,失去资源进入就绪状态。

线程死亡

线程死亡会以一下三种状况结束:

—>调用run或call方法执行完成,正常结束

—>线程抛出一个为捕获的Exception或Error

—>直接调用stop()方法来结束该线程——容易导致死锁,不推荐。

不要试图对死亡的线程使用start()方法,将会抛出异常,并不会重启死亡的异常!

java 线程 状态 图_Java提高——多线程(一)状态图相关推荐

  1. java 线程 状态 图_Java线程中的生命周期和状态控制图文详解

    这篇文章主要介绍了Java线程的生命周期和状态控制,需要的朋友可以参考下 一.线程的生命周期 线程状态转换图: 1.新建状态 用new关键字和Thread类或其子类建立一个线程对象后,该线程对象就处于 ...

  2. java线程的优点_Java使用多线程的优势

    Java使用多线程的优势 如果使用得当,线程可以有效地降低程序的开发和维护等成本,同时提升复杂应用程序的性能.那么Java使用多线程的优势具体有哪些呢,一起来了解一下! 1.发挥多处理器的强大能力 现 ...

  3. java线程不能重复_Java中多线程重复启动

    标签: 在面试时候经常被问到多线程的相关问题: 今天在测试的时候发现下面的代码会抛出异常: java.lang.IllegalThreadStateException public static vo ...

  4. java 线程状态_Java线程为何没有Running状态?我猜你不知道。

    作者:国栋原文:https://my.oschina.net/goldenshaw/blog/705397 Java虚拟机层面所暴露给我们的状态,与操作系统底层的线程状态是两个不同层面的事.具体而言, ...

  5. 【Java多线程】Java线程状态及转换方法详解

    文章目录 1. 现代操作系统中的线程状态及转换(5种) 2. Java 线程状态(6种) 2.1 NEW 创建 2.2 RUNNABLE 运行 2.3 BLOCKED 阻塞 2.4 WAITING 等 ...

  6. java 线程状态_【19期】为什么Java线程没有Running状态?

    Java虚拟机层面所暴露给我们的状态,与操作系统底层的线程状态是两个不同层面的事.具体而言,这里说的 Java 线程状态均来自于 Thread 类下的 State 这一内部枚举类中所定义的状态: 什么 ...

  7. java线程状态和状态切换

    背景 先来探讨一个关于多线程的基础知识:java线程有多少种状态?根据JDK定义,答案是六种!为什么很多人给出的答案却是五种呢?这极有可能是将操作系统层面的线程状态和java线程状态混为一潭了.因为, ...

  8. java 线程状态_关于JAVA线程状态

    最近在复习java基础知识,在看到java多线程知识的时候偶然搜到一篇csdn上的博客. 这篇博客上弄了一张描述java线程状态转换的图,如下 看到的第一眼直觉上告诉这图我哪里不太对,于是我就去了的相 ...

  9. 面试必备,Java线程状态之细节回顾

    点击上方"方志朋",选择"设为星标" 做积极的人,而不是积极废人 来源:https://dwz.cn/vYqjShos Java线程有6种状态 在某个给定时间点 ...

最新文章

  1. 2022-2028年中国企业核心路由交换机行业市场前瞻与投资分析报告
  2. Cloud for Customer里XML view的加载原理
  3. esp8266单片机透传_基于WeMos D1(ESP8266)的校园卡门禁系统
  4. C++中new和malloc
  5. Linux虚拟化KVM-Qemu分析(一)
  6. 云服务器饥荒_运用双腾讯云搭建《饥荒》多人联机服务器
  7. 你真的了解JavaScript的Promise吗?
  8. linux下编辑文件实验,Linux实验_修改
  9. 小米5s升级Android8,小米5s、小米5s Plus升级8.0提前,好消息!
  10. html to pdf
  11. 采用AOP 的观点来 Log 所有方法的调用
  12. udev   ksm
  13. dial协议服务器可以禁吗,Radius协议   1812  radius
  14. 大地主题的解算 matlab,大地主题解算.PPT
  15. 学习整理软测(八)-----数据库命令与操作
  16. B06 - 999、大数据组件学习③ - Hive
  17. 洛谷-P3975 弦论(后缀自动机板子题)
  18. 2022-02-11 学习记录:通过CSS3的clip-path实现多边形
  19. 基于双语数据集搭建seq2seq模型
  20. Linux调整网卡MAC地址(指令)

热门文章

  1. MongoDB监控及报警
  2. idea搭建web项目及tomcat部署总结
  3. Python爬虫:一些常用的爬虫技巧总结
  4. Spring学习笔记--自动装配Bean属性
  5. Powerful Sleep(神奇的睡眠-睡眠生物钟的秘密:如何睡得更少却睡得更好)阅读笔记...
  6. C#.NET中的事件2
  7. 在GZIDG弄服务器的这一整夜,快乐
  8. C++之泛型编程(模板)
  9. 李洋疯狂C语言之有关“you are come from shanghai”逆序(二)
  10. sort,uniq,wc指令简单用法