并发编程学习笔记(一、线程基础)
目录:
- 进程、线程概念及一些注意点
- 线程的创建
- 线程的生命周期
进程、线程及一些注意点:
1、进程:计算机资源分配的基本单位,它让操作系统的并发成为可能。
2、线程:计算机资源调度的基本单位,它让进程内部的并发成为可能。
3、注意点:一个进程虽然包括多个线程,但是这些线程是共同享有进程占有的资源和地址空间的
线程的创建:
1、通过继承Thread创建
1 public class ThreadTest extends Thread { 2 3 @Override 4 public void run() { 5 System.err.println("thread ..."); 6 } 7 8 public static void main(String[] args) { 9 System.err.println("创建线程 ..."); 10 ThreadTest threadTest = new ThreadTest(); 11 System.err.println("启动线程 ..."); 12 threadTest.start(); 13 } 14 }
2、通过实现Runnable接口创建
public class RunnableTest implements Runnable { @Override public void run() { System.err.println("runnable ..."); } public static void main(String[] args) { System.err.println("创建线程 ..."); Thread thread = new Thread(new RunnableTest()); System.err.println("启动线程 ..."); thread.start(); } }
3、通过Callable接口获取线程返回值
public class CallableTest { public static void main(String[] args) throws ExecutionException, InterruptedException { FutureTask<Integer> futureTask = new FutureTask<>(() -> { int result = 0; for (int i = 0; i <= 100; i++) { result += i; } return result; }); FutureTask<String> futureTask2 = new FutureTask<>(() -> { String result = ""; for (int i = 0; i <= 10; i++) { result += i; } return result; }); Thread thread = new Thread(futureTask); thread.start(); System.err.println(futureTask.get()); Thread thread2 = new Thread(futureTask2); thread2.start(); System.err.println(futureTask2.get()); } }
线程的生命周期:
1、创建:new关键字创建对象时的状态。
2、就绪:调用start()方法,线程进入就绪状态,等待CPU调度。
3、运行:获取CPU执行权时允许线程内部程序的状态。
4、阻塞:线程被挂起,或是“睡着”了,通常是在等待另一个锁。
当线程尝试进入一个synchronize的代码块或方法时,如果锁已经被其他线程占用的话就会被阻塞,直到另一个线程走完临界区或执行wait()方法后,当前线程才有机会争夺进入临界区的权力。
5、等待:分为有限等待和无限等待。
- 无限等待:未设置timeout的Object.wait()、Thread.join(),以及LockSupport.park();这种状态下的线程不会被CPU分配执行时间,需要等待其他线程的唤醒。
- 有限等待:Thread.sleep(),设置了timeout的Object.wait()、Thread.join()、LockSupport.parkNanos()、LockSupport.parkUnitl();这种状态下的线程也不会被CPU分配执行时间,在一定时间后会被系统自动唤醒。
6、结束:线程结束,分为运行完毕或中断等等
- 线程逻辑执行完毕
- 未捕获Exception或发生Error
- 执行线程的stop()方法