java多线程(1)
这部分主要介绍Java相关的多线程知识以及多线程相关的常用设计模式,第一部分主要是Java多线程的基础,线程以及并发相关的概念就不在这里赘述了,主要针对Java相关的内容。
线程的启动
利用Thread类的子类
1 | public class NewThread extends Thread { |
首先需要多线程执行的类需要继承Thread类,并重写run方法,新的线程启动后就会执行run方法。具体来说,启动一个新线程需要创建一个继承于Thread类的对象,并调用start方法。我们需要区别,NewThread类并不是线程,创建它并不会启动线程,线程结束NewThread类的实例也不会消失,只有调用start方法才会启动一个线程。
利用Runnable接口
1 | public class NewThread implements Runnable { |
我们可以看到,利用Runnable接口与利用Thread子类很像,都需要在具体类中重写run方法,区别是使用Thread类的子类时我们需要实例化一个子类的实例并调用它的start方法即可,而使用Runnable接口时我们需要把Runnable的对象作为参数去实例化一个Thread对象,并调用Thread类的start方法。
利用concurrent包中的工厂创建
上面利用Runnable接口的方式似乎不够优雅,因为创建时需要连续使用两个new,我们可以利用Java提供的工厂模式来隐藏这一部分。
1 | import java.util.concurrent.Executors; |
获取默认工厂后,把Runnable对象作为参数传给工厂的newThread方法,就可以完成对象的创建过程,然后调用start方法即可启动线程。
线程的暂停
1 | try { |
上面的sleep方法可以使当前线程暂停1000ms,注意使用sleep方法时,需要捕捉InterruptedException异常,关于该异常的具体细节会在后续给出。
线程的互斥
Java使用synchronized关键字来申明只能同时被一个线程执行的方法或代码段。
1 | public synchronized void test() { |
上述的代码表示对test方法加锁,如果一个线程在执行test方法(一个线程获得锁),其他的线程必须等待当前线程释放锁才能执行。
synchronized关键字也可以用于代码块,如上述代码就等价于:
1 | public void test() { |
synchronized关键字后的括号表示获取锁的实例。
线程的协作
每一个线程都有一个等待队列,队列中有等待执行的线程。
已经获取锁的线程可以执行wait()方法,这会使得当前线程暂停执行,进入等待序列并释放锁。
已经获取锁的线程可以执行notify或notifyAll方法,前者随机唤醒等待队列中的一个线程,后者唤醒等待队列中的所有线程,但只有获得锁的线程可以执行。notify方法与notifyAll方法相比效率更高,但notifyAll方法的健壮性更好。
线程的状态变化图

Original author: 马旭
Original link: https://bhmaxu.github.io/2020/03/16/java多线程(1)/
Copyright Notice: Please indicate the source of the reprint (must retain the author's signature and link)