多线程
-
简介
-
-
我们在操作系统上开启了多个应用:微信一个、QQ 一个、网易云音乐一个……CPU 执行代码是顺序一行接着一行的,操作系统让 CPU 多对个任务轮流交替执行,让微信执行1秒,让 QQ 执行 1 秒,再让网易云音乐执行 1秒,CPU 就是在同时执行多个任务,即使是多核 CPU,但任务数量要远远多于 CPU 的核数,所以任务也是交替执行的;
-
我们把一个任务称作一个进程,一个任务内部还需同时执行多个子任务,比如使用 Word,一边输入,一边进行检查,我们把任务中的子任务称作线程;
-
一个进程包含一个或多个线程,至少有一个线程;
-
操作系统调度的最小任务单位是线程,如何调度线程由操作系统决定,程序不能决定什么时候调用,调用多长时间;
-
进程优点:
-
- 稳定性高,一个进程崩溃不会影响别的进程,而多线程中,任何一个线程崩溃都会导致整个进程崩溃;
-
线程优点:
-
- 开销小,创建进程的开销远大于创建线程,尤其在 Windows 系统上;
- 数据通讯速度快,线程间通讯实际就是读同一变量;
-
一个 Java 程序实际就是一个 JVM 进程,用一个主线程来执行 main() 方法,在 main() 方法内部,我们可以启动多个线程,此外,JVM 还负责垃圾回收等线程;
-
多线程编程时,我们需要经常读写共享数据,并且需要同步,比如,播放器播放电影时,一个线程播放视频,一个线程播放音频,两个线程需要协调运行,否则,画面和声音就不同步,所以,多线程编程复杂度高、调试困难;
-
-
创建线程
-
继承 Thread 类,重写 run 方法;
-
实现 Runnable 接口,实现 run 方法;
-
实现 Callable 接口,实现 call 方法;
-
public class MyThread extends Thread { @Override public void run() { System.out.println("==== 开启线程1 ===="); } } public class MyRunnable implements Runnable { @Override public void run() { System.out.println("==== 开启线程2 ===="); } } public class MyCallable implements Callable<String> { @Override public String call() throws Exception { System.out.println("==== 开启线程3 ===="); return "Hello"; } } public class ThreadTest { // 创建线程 public void createThread() { System.out.println("==== 主线程开始 ===="); // 方式一:继承 Thread 类,并重写 run 方法 MyThread thread1 = new MyThread(); thread1.start(); // 方式二:实现 Runnable,实例传入 Thread 构造器 MyRunnable myRunnable = new MyRunnable(); Thread thread2 = new Thread(myRunnable); thread2.start(); // 方法三:实现 Callable MyCallable myCallable = new MyCallable(); ExecutorService executorService = Executors.newSingleThreadExecutor(); Future<String> future = executorService.submit(myCallable); try { System.out.println(future.get()); } catch (InterruptedException | ExecutionException e) { e.printStackTrace(); } executorService.shutdown(); System.out.println("==== 主线程结束 ===="); } public static void main(String[] args) { ThreadTest threadTest = new ThreadTest(); threadTest.createThread(); } }
-
-
线程的五种状态
- New:创建状态;
- Runnable:就绪状态;
- Running:运行状态;
- Blocked:阻塞状态;
- Terminated:死亡状态;