概念
进程与线程
- 进程:一个应用就是一个进程,如360安全卫士本身是一个进程
- 线程:一个进程的执行单元,如360的电脑优化、木马查杀等功能
作用:提高效率
并发与并行
- 并发:再同一时刻,有多个指令在单个CPU上
交替
执行 - 并行:在同一时刻,在多个指令在多个CPU上
同时
进行
实现方式
- 继承Thread类
- 实现Runnable接口的方式
- 利用Callable接口和Future接口方式实现
方法三能够获取多线程执行结果
方法一:
//新建一个类,继承Thread类
public class OneThread extends Thread{
//重写Run方法
public void run(){
//要多线程执行的代码
}
}
class Test{
public static void main(String[] args){
//创建新建类的实例
OneThread t = new OneThread();
//开启线程
t.start();
//如果要利用多个线程,只需要建多个实例对象
OneThread t1 = new OneThread();
OneThread t2 = new OneThread();
t1.start();
t2.start();
}
}
方式二:
//新建一个类,实现 Runnable接口
public class MyThread implements Runnable{
//实现run方法
public void run(){
//想要利用多线程执行的代码
}
}
class Test{
public static void main(String[] args){
MyThread mt = new MyThread();
Thread t = new Thread(mr);
//开启线程
t.start();
}
}
方式三:
//新建一个类实现Callable接口
//注意此处的泛型为结果的泛型,此处以返回整数型为例
public class MyCallable implements Callable<Integer>{
//重写Callable中的call方法
public Integer call() throws Exception {
//此处为要利用多线程执行的代码
int number = 1;
return number;
}
}
class{
public static void main(String[] args) throw Exception{
//创建MyCallable的实例
MyCallable mc = new MyCallable();
//创建FutureTask的实例,用来管理多线程运行的结果
FutureTask<Integer> ft = new FutureTask<>(mc);
//创建线程对象
Thread t1 = new Thread(ft);
//启动线程
t1.start();
//获取多线程运行的结果
int result= ft.get();
}
}
Thread类中成员方法
基本方法
基本方法 | 说明 |
---|---|
String getName() | 获取线程的名字 |
void setName() | 设置线程的名称(构造方法也可以设置名称) |
static Thread currentThread() | 获取当前线程的对象 |
static void sleep(Long time) | 让线程休眠指定的时间ms |
优先级方法
Java中采用抢占式调度,所有的线程都是随机执行的
优先级方法 | 说明 |
---|---|
setPriority(int newPriority) | 设置线程的优先级 |
final int getProiority() | 获取线程的优先级 |
Java中线程的优先级最低是
1
,最高是10
,如果没有赋值,则默认
是5
守护线程
final void setDaemon(boolean on)
ture:设为守护线程
当非守护线程执行结束之后,守护线程会陆续结束(即使代码块没有执行完毕)
插入线程
public final void join()
将使用该方法的线程插入到当前方法之前。
线程的生命周期
- 刚创建线程对象的
新建状态
- 一直在抢夺执行权的
就绪状态
- 抢夺到执行权的
运行状态
- 遇到sleep或其他阻塞式方法的
阻塞状态
- 线程中代码执行完成后的
死亡状态
注意:
- 线程在
运行期间
有可能会被其他线程抢走执行权
,从而回到就绪状态
- 阻塞状态结束后,线程会回到就绪状态重新抢夺执行权
同步代码块
由于Java中线程在执行的任何时间都会被抢夺走执行权,如果我们需要让这个线程执行完某个步骤才让其能被夺走,我们可以使用锁
来“锁住”这个线程。
格式:
synchronized (锁对象){
操作共享数据的代码
}
注意:锁对象一定是唯一的,一般写为当前类的字节码文件对象如:MyThread.class
特点:
- 锁默认打开,有一个线程进去锁会自动关闭
- 里面的代码全部执行完毕,线程出来锁才会自动打开