一、线程的概念
线程:进程内的执行单元,也叫轻量级进程,一个进程可包含多个线程同时执行不同任务。
主线程:从main方法开始执行,以main方法退出为结束,main函数是其执行体。
线程组成
CPU:由操作系统分配时间片;
数据:堆空间共享,栈空间独立(每个线程有专属栈空间);
程序代码。
二、线程的创建方式
方式1:实现Runnable接口
定义类实现java.lang.Runnable接口,并重写run()方法(封装线程任务);
创建目标对象:MyTask task = new MyTask();;
创建线程对象并传入目标对象:Thread t1 = new Thread(task);;
开启线程:t1.start();。
方式2:继承Thread类
定义子类继承java.lang.Thread类,并重写run()方法;
创建线程对象:MyThread t2 = new MyThread();;
开启线程:t2.start();。
三、线程的状态
初始状态(New):线程对象被创建,仅在堆中开辟内存,与常规对象无异。
就绪状态(Ready):调用start()后进入,等待操作系统选中并分配时间片。
运行状态(Running):获得时间片后执行,时间片到期则回到就绪状态。
终止状态(Terminated):run()方法结束,线程任务完成并释放时间片。
计时等待(Timed Waiting):调用sleep(long m)后进入,超时后回到就绪状态。
无计时等待(Waiting):调用join()或等待数据输入时进入,条件满足后回到就绪状态。
阻塞状态(Blocked):获取同步锁失败时进入,获得锁后回到就绪状态。
状态流转关键:
start():New → Ready;
操作系统选中:Ready → Running;
时间片到期:Running → Ready;
sleep()/join():Running → 等待状态;
同步锁竞争失败:Running → Blocked;
run()结束:Running → Terminated。
四、线程的常见方法
休眠:public static void sleep(long m)
让当前线程休眠m毫秒,进入计时等待状态,同时释放CPU资源。
结合:public final void join()
让调用该方法的线程优先执行,当前线程等待其执行完毕后再继续;如main中调用t1.join(),主线程会让步于t1线程。
五、线程同步
线程异步问题
多线程同时操作共享资源(临界资源)时,会出现数据不一致的问题(如多线程向同一数组添加元素,可能出现覆盖、计数错误)。
同步代码块
作用:对临界资源加锁,保证原子操作的执行唯一性。
语法(定义在方法内部):
synchronized(临界资源对象) {
// 原子操作代码
}