Java并发编程
进程与线程的概念
(1)什么是进程
进程:程序由指令和数据组成,
(2)什么是线程
- 一个进程可以有多个线程
- 一个线程就是一个指令流,将指令流中的一条条指令以一定的顺序交给CPU执行
- 线程作为任务调度的最小单位,进程作为资源分配的最小单位
并发与并行的概念
(1)什么是并发(Concurrent)
同一时刻多个线程轮流使用CPU,并不是同时执行的。
(1)什么是并行
同一时刻多个线程同时使用CPU,一般是多核CPU,因此是同时执行的。
创建线程的方法
继承Thread类
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| public class Concurrent { public static void main(String[] args) { MyThread myThread = new MyThread(); myThread.setName("子线程:"); myThread.start(); }
}
class MyThread extends Thread{ public void run(){ for(int i = 0;i < 5; i++){ System.out.println(Thread.currentThread().getName() + i); } } }
|
实现Runnable接口
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| public class Concurrent { public static void main(String[] args) { Thread thread = new Thread(new MyRunnable()); thread.setName("子线程:"); thread.start(); }
}
class MyRunnable implements Runnable {
@Override public void run() { for (int i = 0; i < 5; i++) { System.out.println(Thread.currentThread().getName() + i); } } }
|
实现Callable接口
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
| public class Concurrent { public static void main(String[] args) { FutureTask<Integer> futureTask = new FutureTask<Integer>(new MyCallable()); new Thread(futureTask).start(); try { Integer sum = futureTask.get(); System.out.println(sum); } catch (InterruptedException e) { e.printStackTrace(); } catch (ExecutionException e) { e.printStackTrace(); } }
}
class MyCallable implements Callable<Integer> {
@Override public Integer call() throws Exception { int sum = 0; for (int i = 0; i < 5; i++) { sum += i; } return sum; } }
|
使用线程池
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| public class Concurrent { public static void main(String[] args) { ExecutorService executorService = Executors.newFixedThreadPool(5); ThreadPool threadPool = new ThreadPool(); executorService.submit(threadPool); executorService.shutdown(); } }
class ThreadPool implements Runnable {
@Override public void run() { for (int i = 0; i < 5; i++) { System.out.println(Thread.currentThread().getName() + ":" + i); } } }
|
主线程和守护线程
默认情况下,Java进程需要等待所有线程都运行结束才会结束
守护线程:只要其他非守护线程都运行结束了,即使守护线程的代码没有执行完,也会强制结束。
启动之前:thread.setDaemon(true);即可设置该线程为守护线程。
垃圾回收线程就是一种守护线程。
线程的几种状态
从操作系统层面(五种)

新建/初始状态
新创建了一个线程对象。
就绪/可运行状态
指该线程已经被创建,等待 CPU 调度执行。
运行状态
指获取了 CPU 时间片运行中的状态
当 CPU 时间片用完,会从【运行状态】转换至【可运行状态】,会导致线程的上下文切换
阻塞状态
等 BIO 操作完毕,会由操作系统唤醒阻塞的线程,转换至【可运行状态】
与【可运行状态】的区别是,对于【阻塞状态】的线程来说只要它们一直不唤醒,调度器就一直不会考虑调度它们
死亡状态
表示线程已经执行完毕,生命周期已经结束,不会再转换为其它状态
参考:
线程的5种状态详解
从JAVA层面(六种)

初始状态
新创建了一个线程对象,但还没有调用start()方法。
运行状态
Java线程中将就绪(ready)和运行中(running)两种状态笼统的称为“运行”。
线程对象创建后,其他线程(比如main线程)调用了该对象的start()方法。该状态的线程位于可运行线程池中,等待被线程调度选中,获取CPU的使用权,此时处于就绪状态(ready)。就绪状态的线程在获得CPU时间片后变为运行中状态(running)。
阻塞状态
表示线程阻塞于锁。
等待状态
进入该状态的线程需要等待其他线程做出一些特定动作(通知或中断)。
超时等待状态
该状态不同于等待(WAITING),它可以在指定的时间后自行返回。
终止状态
表示该线程已经执行完毕。
参考:
Java线程的6种状态及切换
线程的状态在操作系统层面和JAVA API层面的区别
Sleep和Wait的区别

Run和Start的区别
