目录
- 多线程简介
- 进程
- 线程
- 多线程实现方式
- 继承Thread
- 实现Runable接口
- 实现Callable接口
- 线程状态
- 三种阻塞
- 多线程状态流程
1.多线程简介:
多线程并发编程是Java编程中重要的一块内容,本文主要讲了java中多线程的实现方式、线程状态切换。在这之前,首先让我们来了解下在操作系统中进程和线程的区别
1.1 进程
每个进程都有独立的代码和数据空间(进程上下文),进程间的切换会有较大的开销,一个进程包含1–n个线程。(进程是资源分配的最小单位)
1.2 线程
同一类线程共享代码和数据空间,每个线程有独立的运行栈和程序计数器(PC),线程切换开销小。(线程是cpu调度的最小单位)
2. 多线程实现方式:
2.1 继承Thread
/**
* @program: concurrent
* @description: 继承Thread类的方式
* @author: chengqj
* @create: 2018-11-19 20:51
**/
public class ThreadMethod extends Thread{
@Override
public void run() {
System.out.println("继承Thread的方式");
}
public static void main(String[] args) {
ThreadMethod tm = new ThreadMethod();
tm.start();
}
}
2.2 实现Runable接口
/**
* @program: concurrent
* @description: 实现Runnable接口的方式
* @author: chengqj
* @create: 2018-11-19 20:52
**/
public class RunnableMethod implements Runnable{
@Override
public void run() {
System.out.println("实现runnable的方式");
}
public static void main(String[] args) {
Thread td = new Thread(new RunnableMethod());
td.start();
}
}
2.3 实现Callable接口
/**
* @program: concurrent
* @description: 实现Callable的方式
* @author: chengqj
* @create: 2018-11-19 20:55
**/
public class CallableMethod implements Callable {
@Override
public Object call() throws Exception {
System.out.println("实现callable的方式");
return "callable";
}
public static void main(String[] args) throws ExecutionException, InterruptedException {
ExecutorService es = Executors.newCachedThreadPool();
Future future = es.submit(new CallableMethod());
//会阻塞,等到线程执行完返回值
System.out.println(future.get());
FutureTask<String> ft = new FutureTask<>(new CallableMethod());
new Thread(ft).start();
//会阻塞,等到线程执行完返回值
System.out.println(ft.get());
}
}
3. 线程状态
状态 | 说明 |
---|---|
新建(New) | 新创建了一个线程对象 |
就绪(Runnable) | 线程对象创建后,其他线程调用了该对象的start()方法。该状态的线程位于可运行线程池中,变得可运行,等待获取CPU的使用权 |
运行(Running) | 就绪状态的线程获取了CPU,执行程序代码 |
阻塞(Blocked) | 阻塞状态是线程因为某种原因放弃CPU使用权,暂时停止运行。直到线程进入就绪状态,才有机会转到运行状态 |
终止(Dead) | 线程执行完了或者因异常退出了run()方法,该线程结束生命周期 |
3.1 三种阻塞
阻塞情形 | 进入条件 |
---|---|
等待阻塞 | 运行的线程执行wait()方法,JVM会把该线程放入等待池中。(wait会释放持有的锁) |
同步阻塞 | 运行的线程在获取对象的同步锁时,若该同步锁被别的线程占用,则JVM会把该线程放入锁池中 |
其他阻塞 | 运行的线程执行sleep()或join()方法,或者发出了I/O请求时,JVM会把该线程置为阻塞状态。当sleep()状态结束、join()等待线程终止或者超时、或者I/O处理完毕时,线程重新转入就绪状态 |