前言:

这篇文章主要就什么是进程、什么是线程、线程的五个状态、线程的终止来展开讲解java多线程的知识点。

正文:

一、什么是进程?

   
进程是系统进行资源分配和调度的基本单位,它是程序执行时的一个实例。程序运行时系统就会创建一个进程,并为它分配资源,然后把该进程放入进程就绪队列,进程调度器选中它的时候就会为它分配CPU时间,程序开始真正运行。

二、什么是线程?

 
 线程是操作系统能够进行运算调度的最小单位。它被包含在进程之中,是进程中的实际运作单位。一条线程指的是进程中一个单一顺序的控制流,一个进程中可以并发多个线程,每条线程并行执行不同的任务。

三、进程和线程的关系


通常在一个进程中可以包含若干个线程,它们可以利用进程所拥有的资源,在引入线程的操作系统中,通常都是把进程作为分配资源的基本单位,而把线程作为独立运行和独立调度的基本单位,由于线程比进程更小,基本上不拥有系统资源,故对它的调度所付出的开销就会小得多,能更高效的提高系统内多个程序间并发执行的程度。

四、线程的状态

我们可以通过打开java.lang.thread的源码里看到,线程定义的6个状态

1.New: 尚未启动的线程的线程状态。

2.Runnable: 可运行线程的线程状态,等待CPU调度。

3.Blocked: 线程阻塞等待监视器锁定的线程状态。

4.Waiting:等待线程的线程状态。下列不带超时的方式:

Object.wait、Thread.join、LockSupport.park

5.Timed Waiting:具有指定等待时间的等待线程状态。下列带超时的方式


Thread.sleep、Object.wait、Thread.join、LockSupport.parkNanos、LockSupport.parkUntil

6. Terminated:线程终止的状态。线程正常完成执行或者出现异常。
public enum State { /** * Thread state for a thread which has not yet started.
*/ NEW, /** * Thread state for a runnable thread. A thread in the runnable *
state is executing in the Java virtual machine but it may * be waiting for
other resources from the operating system * such as processor. */ RUNNABLE, /**
* Thread state for a thread blocked waiting for a monitor lock. * A thread in
the blocked state is waiting for a monitor lock * to enter a synchronized
block/method or * reenter a synchronized block/method after calling * {@link
Object#wait() Object.wait}. */ BLOCKED, /** * Thread state for a waiting
thread. * A thread is in the waiting state due to calling one of the *
following methods: * <ul> * <li>{@link Object#wait() Object.wait} with no
timeout</li> * <li>{@link #join() Thread.join} with no timeout</li> *
<li>{@link LockSupport#park() LockSupport.park}</li> * </ul> * * <p>A thread in
the waiting state is waiting for another thread to * perform a particular
action. * * For example, a thread that has called <tt>Object.wait()</tt> * on
an object is waiting for another thread to call * <tt>Object.notify()</tt> or
<tt>Object.notifyAll()</tt> on * that object. A thread that has called
<tt>Thread.join()</tt> * is waiting for a specified thread to terminate. */
WAITING, /** * Thread state for a waiting thread with a specified waiting time.
* A thread is in the timed waiting state due to calling one of * the following
methods with a specified positive waiting time: * <ul> * <li>{@link #sleep
Thread.sleep}</li> * <li>{@link Object#wait(long) Object.wait} with
timeout</li> * <li>{@link #join(long) Thread.join} with timeout</li> *
<li>{@link LockSupport#parkNanos LockSupport.parkNanos}</li> * <li>{@link
LockSupport#parkUntil LockSupport.parkUntil}</li> * </ul> */ TIMED_WAITING, /**
* Thread state for a terminated thread. * The thread has completed execution.
*/ TERMINATED; }
这里我写个Demo,来看下状态的变换
public static void main(String[] args) throws InterruptedException {
//第一种状态切换 - 新建 -> 运行 -> 终止 System.out.println("######第一种状态切换 - 新建 -> 运行 ->
终止############################"); Thread thread1 = new Thread(new Runnable() {
@Override public void run() {
System.out.println("thread1当前状态:"+Thread.currentThread().getState().toString());
System.out.println("thread1 执行了"); } });
System.out.println("没调用start方法,thread1当前状态:"+thread1.getState().toString());
thread1.start(); Thread.sleep(2000L);//等待thread1执行结束,再看状态
System.out.println("等待两秒,再看thread1当前状态:"+thread1.getState().toString());
//thread1.start(); //TODO注意,线程终止之后,再进行调用,会抛出IllegalThreadStateException异常 }
 运行的结果打印:
######第一种状态切换 - 新建 -> 运行 -> 终止############################
没调用start方法,thread1当前状态:NEW thread1当前状态:RUNNABLE thread1 执行了
等待两秒,再看thread1当前状态:TERMINATED

其他的状态,可以编写一下试试,有的文章里会写在可运行状态前有种状态叫做就绪状态是Runnable,运行时状态是Running,但是如果你打印线程当前的运行状态其实是Runnable。

 四、线程的终止

1.不正确的终止方式


thread.stop方法终止线程,会导致线程不安全。通俗的说,即使你在run()方法的代码块里加上synchronized关键字,也无法保证原子性操作,因为stop会破会这个原子性,拦腰折断
public class StopThread extends Thread { private int i = 0, j = 0; @Override
public void run() { synchronized (this) { //增加同步锁,确保线程安全 ++i; try {
//休眠10秒,模拟耗时操作 Thread.sleep(10000); } catch (InterruptedException e) {
e.printStackTrace(); } ++j; } } public void print(){
System.out.println("i="+i+"j="+j); } public static void main(String[] args)
throws InterruptedException { StopThread thread = new StopThread();
thread.start(); //休眠1秒,确保i变量自增成功 Thread.sleep(1000); thread.stop();//错误的终止
Thread.sleep(1000); System.out.println(thread.isAlive()); while
(thread.isAlive()){ //确保线程已经终止 } thread.print(); }
 运行结果:
false i=1j=0
我们可以明显看到,i和j的结果不一样,破坏了 synchronized关键字同步效果。

2.正确的终止方式
2.1调用thread.interrupt()方法就可以正确终止线程。把上面的例子改成interrupt来终止线程,i与j的结果就保持一致。 public
static void main(String[] args) throws InterruptedException { StopThread thread
= new StopThread(); thread.start(); //休眠1秒,确保i变量自增成功 Thread.sleep(1000);
hread.interrupt();//正确的终止 Thread.sleep(1000);
System.out.println(thread.isAlive()); while (thread.isAlive()){ //确保线程已经终止 }
thread.print(); }
运行后的结果: 
java.lang.InterruptedException: sleep interrupted at
java.lang.Thread.sleep(Native Method) at
com.study.oa.study.StopThread.run(StopThread.java:13) false i=1j=1
 2.2 还可以用标志位来正确终止线程
public class Demo4 extends Thread{ public volatile static boolean flag=true;
public static void main(String[] args) throws InterruptedException { new
Thread(() ->{ try { while (flag){//判断是否运行 System.out.println("运行中");
Thread.sleep(1000L); } }catch (InterruptedException e){ e.printStackTrace(); }
}).start(); //3秒之后,将状态标志改为false,代表不继续运行 Thread.sleep(3000L); flag=false;
System.out.println("程序运行结束"); } }
参考内容:以上的内容来自个人总结于网易云课堂的学习。

总结:


线程的学习坑点有很多,大家一定要有耐心,因为想迈入高级java编程,多线程开发是无法避免的。我是阿达,一名喜欢分享知识的程序员,时不时的也会荒腔走板的聊一聊电影、电视剧、音乐、漫画,这里已经有172位小伙伴在等你们啦,感兴趣的就赶紧来点击关注我把,哪里有不明白或有不同观点的地方欢迎留言。

友情链接
KaDraw流程图
API参考文档
OK工具箱
云服务器优惠
阿里云优惠券
腾讯云优惠券
华为云优惠券
站点信息
问题反馈
邮箱:[email protected]
QQ群:637538335
关注微信