实现方式
1.自定义线程类
extends Thread
重写 run 方法
创建自定义的线程对象
开启线程 start()
2.自定义一个任务类
implements Runnable
重写 run 方法
创建自定义的任务对象
通过任务对象, 构造一个线程对象
开启线程 start()
3.匿名内部类
上述两种方法的匿名内部类
构造方法
1.new 自定义线程类(): 自定义类的构造方法, 随意
2.new Thread(): 无参构造器
3.new Thread(String): String->指定的线程名
4.new Thread(Runnable): Runnable->线程任务
5.new Thread(Runnable, String): Runnable->线程任务, String->指定的线程名
API
Thread.currentThread()
获得当前的对象线程
getName()
获得线程对象的名字
getPriority()
返回此线程的优先级
优先级:(0~10),数字越大优先级越高
作用:改变CPU分配时间片的概率
setPriority(int): 设置线程的优先级
isDaemon()
测试这个线程是否是守护线程
守护线程:当所有的前台线程结束, 守护线程也会自动结束
eg.GC(垃圾资源回收机制)
setDaemon(boolean): 将这个线程是设置为守护线程
sleep(long)
线程休眠指定时间,会返回一个已检查异常,需要try-catch
join()
等待调用这个方法的线程结束, 再继续后续代码,
会返回一个已检查异常,需要try-catch
yield()
主动放弃cpu的时间片
线程同步
synchronized
线程同步锁
1.加到方法上:同步方法锁
锁普通方法: 就是锁this对象
锁静态方法: 锁 类.class(类的字节码) 对象
2.加到代码上:借助共享资源同步代码
Lock接口
创建对象:ReentrantLock lock = new ReentrantLock();
加锁: 锁对象.lock();
解锁: 锁对象.unlock();
线程通信
wait()
线程等待,只能被notify(),notifyAll()唤醒
wait(long):到时间以后, 自动醒来
notify()
唤醒一个线程, 只能唤醒等待时间久的那个线程
notifyAll():唤醒所有正在等待的线程
线程安全
如果有多个线程在同时运行,而这些线程可能会同时运行这段代码。程序每次运行结果和单线程运行结果是一样的,而且其他的变量的值也和预期的是一样的,就是线程安全的。
线程状态:
1.new - 对象
2.start() -> 就绪状态/可执行状态 Runnable
3.cpu分配时间片 -> 运行状态 running
4.run方法结束 -> 死亡状态/被终止
5.run->就绪状态: 时间片到期/yield()
6.run:阻塞状态
1.锁阻塞: 同步锁
2.计时等待: sleep(long) wait(long)
3.无限等待: wait()
唤醒: notify() notifyAll()
4.a.join(): 调用这个方法的线程进入阻塞
线程池:Executors
newCachedThreadPool()
创建一个根据需要创建新线程的线程池,但在可用时将重新使用以前构造的线程。
newFixedThreadPool(int nThreads)
创建一个线程池,该线程池重用固定数量的从共享无界队列中运行的线程。
newScheduledThreadPool(int corePoolSize)
创建一个线程池,可以调度命令在给定的延迟之后运行,或定期执行。
newSingleThreadExecutor()
创建一个使用从无界队列运行的单个工作线程的执行程序。
线程池的好处
自行查询。
Callable
只能在线程池中使用的线程任务,有返回值
get()
得到call方法的返回值,可能会遇到阻塞
get(long, TimeUnit.时/分/秒。。。):超时继续