线程的创建和使用
Java语言的JVM允许程序运行多个线程,它通过java.lang.Thread类来实现。
Thread类的特性
- 每个线程都是通过某个特定的Thread对象的run()方法来完成操作的,经常把run()方法的主体称为线程体。
- 通过Thread对象的start()方法来启动这个线程,而非直接调用run()
构造器
-
Thread():创建新的Thread对象
-
Thread(String threadname):创建线程并且指定线程实例名
-
Thread(Runnable target):指定创建线程的目标对象,它实现了Runnable接口中的run方法
-
Thread(Runnable target,String name):创建新的Thread对象
方式一:继承Thread类
-
定义子类继承Thread类。
-
子类中重写Thread类中的run方法。
-
创建Thread子类对象,即创建了线程对象。
-
调用线程对象start方法:启动线程,调用run方法。
注意点:
-
如果自己手动调用run()方法,那么就只是普通方法,没有启动多线程模式。
-
run()方法由JVM调用,什么时候调用,执行的过程控制都有操作系统的CPU 调度决定。
-
想要启动多线程,必须调用start方法。
-
一个线程对象只能调用一次start()方法启动,如果重复调用了,则将抛出以上 的异常“IllegalThreadStateException”。
* 测试Thread中的常用方法 * 1、start():启动当前线程 调用当前线程的run() * 2、run(): 需要重写Thread类中的此方法 将创建的线程要执行的操作声明在此方法中 * 3、currentThread(): 静态方法 返回执行当前代码的线程 * 4、getName(): 获取当前线程的名字 * 5、setName(): 设置当前线程的名字 带参构造器 * 6、yield(): 释放当前CPU的执行权 * 7、join(): 在线程A中调用线程B的join(),此时线程A就进入阻塞方法 直到线程执行完以后,线程A才技术阻 塞状态 * 8、stop(): 强制线程生命结束 * 9、sleep(long,millitime): 让当前线程在指定时间内睡眠 当前线程是阻塞状态 * 10、isAlive(): 判断当前线程是否存活 * * 1、线程的优先级 * MAX_PRIORITY:10 * MIN _PRIORITY:1 * NORM_PRIORITY:5 * 2、如何获取当前线程的优先级 * getPriority() :返回线程优先值 * setPriority(int newPriority) :改变线程的优先级 *3、说明 * 线程创建时继承父线程的优先级 * 低优先级只是获得调度的概率低,并非一定是在高优先级线程之后才被调用
方式二:实现Runnable接口
-
定义子类,实现Runnable接口 implements Runnable
-
自类重写Runnable接口中的run方法 punlic void run(){}
-
通过Thread类含参构造器创建线程对象 Thread thread=new Thread(runable)
-
将Runnable接口的子类对象作为实际参数传递给Thread累的构造器中 Runable runable=new Runable()
-
调用Thread类的start方法:开启线程,调用Runnable子类接口的run方法 thread.satrt()
继承方式和实现方式的联系和区别
-
联系
两种方式都需要重写run(),将线程要执行的逻辑声明在run()中
-
区别
继承Thread:线程代码存放Thread子类run方法中。
实现Runnable:线程代码存在接口的子类的run方法 。
-
实现方式的好处
避免了单继承的局限性
多个线程可以共享同一个接口实现类的对象,非常适合多个相同线 程来处理同一份资源(共享数据)。
方式三:新增线程创建方式
新增方式一:实现Callable接口
- 与使用Runnable相比,Callable功能更加强大
- 相比run()方法,可以有返回值
- 方法可以抛出异常
- 支持泛型的返回值
- 需要借助FutureTask类,比如获取返回结果
- Future接口
- 可以对具体Runnable、Callable任务的执行结果进行取消、查询是否完成、获取结果等
- FutureTask是Future接口的唯一的实现类
- FutureTask同时实现了Runnable、Future接口,它既可以作为Runnable被线程执行,又可以作为Future得到Callable的返回值
方式四:线程池
线程的分类
Java中的线程分为两类:守护线程、用户线程
-
他们在几乎每个方面都是相同的,唯一的区别就是判断JVM何时离开。
-
守护线程是用来服务用户线程的,通过在start()方法前调用
thread.setDaemon(true)可以把一个用户线程变为一个守护线程
-
Java垃圾回收就是一个典型的守护线程
-
若JVM中都是守护线程,当前JVM将退出
1、谈谈你对程序、进程、线程的理解。(例如360)
程序:为了完成某项特定任务,用某种语言编写的一组指令的集合。是一段静态代码,静态对象。
进程:正在运行的一个程序,是程序的一次执行过程。
线程:一个程序内部的一次执行路径
2、联系
进程可以细化为多个线程
每个线程,拥有自己独立的:栈、程序计数器
多个线程,共享同一进程中的结构:方法区、堆