核心技术:并发

来自Wikioe
Eijux讨论 | 贡献2020年10月19日 (一) 19:11的版本 →‎线程状态
跳到导航 跳到搜索


什么是线程

一个程序同时执行多个任务,每一个任务称为一个线程(thread), 它是线程控制的简称。

  • 进程与线程有的区别,在于每个进程拥有自己的一整套变量, 而线程则共享数据。
    共享变量使线程之间的通信比进程之间的通信更有效、更容易。

使用线程

实现线程的两种方式:

  1. 实现Runnable接口,利用接口构造Thread对象;(Runnable 是一个函数式接口,可以用lambda 表达式)
    Runnable r = () -> { /*task code*/ };
    Thread t = new Thread(r);
    
  2. 继承Thread类,构造一个子类的对象;
    class MyThread extends Thread
    {
       public void run()
       {
          //task code
       }
    }
    


  • 不要调用Thread类或Runnable对象的run方法,而应该调用Thread.start方法。
    直接调用run 方法,只会执行同一个线程中的任务,而不会启动新线程。
  • 如果有很多任务, 要为每个任务创建一个独立的线程所付出的代价太大了。可以使用线程池来解决这个问题


相关方法

java.Iang.Thread
  • Thread( Runnable target )
    构造一个新线程, 用于调用给定目标的nm() 方法。
  • void start( )
    启动这个线程, 将引发调用mn() 方法。这个方法将立即返回, 并且新线程将并发运行。
  • void run( )
    调用关联 Runnable 的run 方法。
  • static void sleep(long minis)
    休眠给定的毫秒数。参数:millis 休眠的毫秒数
java.lang.Runnable
  • void run( )
    必须覆盖这个方法, 并在这个方法中提供所要执行的任务指令。

中断线程

当线程的run 方法执行方法体中最后一条语句后,并经由执行return 语句返冋时,或者出现了在方法中没有捕获的异常时,线程将终止。

  • 在Java 的早期版本中,还有一个stop方法,其他线程可以调用它终止线程。
    因为,stop会瞬间强行停止一个线程,且该线程持有的锁并不能释放;所以,这个方法现在已经被弃用了。



相关方法

java.Iang.Thread
  • void interrupt()
    向线程发送中断请求。线程的中断状态将被设置为true。如果目前该线程被一个sleep调用阻塞,那么, InterruptedException 异常被抛出。
  • static boolean interrupted()
    测试当前线程(即正在执行这一命令的线程)是否被中断。注意,这是一个静态方法。这一调用会产生副作用—它将当前线程的中断状态重置为false
  • boolean islnterrupted()
    测试线程是否被终止。不像静态的中断方法,这一调用不改变线程的中断状态。
  • static Thread currentThread()
    返回代表当前执行线程的Thread 对象。

线程状态

线程状态.png

线程可以有如下6 种状态:

  1. New ( 新创建)
  2. Runnable (可运行)
  3. Blocked ( 被阻塞)
  4. Waiting ( 等待)
  5. Timed waiting (计时等待)
  6. Terminated ( 被终止)
  • 可调用“getState”方法获取一个线程的当前状态;


Java线程状态图.jpeg

新创建线程

用 new 操作符创建一个新线程,未调用 start 方法,该线程还没有开始运行,即 New 状态

可运行线程

一旦调用 start 方法,则线程处于 runnable 状态。

  • (Java 的规范说明没有将它作为一个单独状态:正在运行中的线程仍然处于可运行状态。)


结合线程状态图,理解为:“可运行” = “运行” + “就绪”

被阻塞线程和等待线程

当线程处于被阻塞或等待状态时,它暂时不活动。它不运行任何代码且消耗最少的资源。直到线程调度器重新激活它。

阻塞(blocked)

阻塞:当一个线程请求锁,而该资源被其他线程持有时,该线程被置为阻塞状态

  • 请求内部的对象锁(非java.util.concurrent库中的锁)。

等待(waiting)

等待:当线程等待另一个线程通知调度器一个条件时,该线程主动进入等待状态
如:

  1. Object.wait
  2. Thread.join
  3. java.util.concurrent 库中的Lock 或Condition

计时等待(timed waiting)

计时等待状态将一直保持到超时期满或者接收到适当的通知。
如:

  1. Object.wait(long millis)
  2. Thread.join(long millis)
  3. java.util.concurrent 库中的Lock(long millis) 或Condition(long millis)


被终止的线程(Terminated)

线程因如下两个原因之一而被终止:

  1. 因为run 方法正常退出而自然死亡。
  2. 因为一个没有捕获的异常终止了nm 方法而意外死亡。
  • 不应该使用“stop”方法来终止线程!(虽然能做到)

相关方法

java.iang.Thread
  • void join()
    等待指定线程的终止。【在当前线程调用“s.join();”,则必须等待线程s执行完毕,当前线程才能继续执行】
  • void join(long mi11is)
    等待指定的线程死亡或者经过指定的毫秒数。
  • Thread.State getState()
    得到这一线程的状态;NEW、RUNNABLE、BLOCKED、WAITING、TIMED_WAITING 或 TERMINATED 之一。
  • void stop()
    停止该线程。这一方法已过时。
  • void suspend()
    暂停这一线程的执行。这一方法已过时。
  • void resume()
    恢复线程。这一方法仅仅在调用suspend() 之后调用。这一方法已过时。

线程属性

同步

阻塞队列

线程安全的集合

Callable 与 Future

执行器

同步器

线程与Swing