目录
1.多线程的作用
2.示例:分别对两个变量实现10亿次自增
1.使用串行(单线程)
2.使用并行(多线程)
结果显示:
3.线程的类构造方法
代码展示:
4.Thread类的常见属性
1.演示各个属性
2.演示后台线程
3.演示线程是否存活
4.线程中断
1.通过是否中断的标志位
2. 通过调用Thread类提供的interruped()方法来中断线程
5.线程等待
6.获取当前线程
7.休眠当前线程
面试题:start()和run()方法的区别?
8.线程状态
1.多线程的作用
使用多线程主要是为了充分利用CPU资源,提升程序运行的效率
2.示例:分别对两个变量实现10亿次自增
1.使用串行(单线程)
private static void serial() {
//开始时间
long start = System.currentTimeMillis();
long a = 0l;
for (long i = 0; i < COUNT; i++) {
a++;
}
long b = 0l;
for (int i = 0; i < COUNT; i++) {
b++;
}
//结束时间
long end = System.currentTimeMillis();
System.out.println("串行总耗时"+(end - start));
}
2.使用并行(多线程)
private static void concurrency() {
long start = System.currentTimeMillis();
//定义两个线程
Thread t1 = new Thread(new Runnable() {
@Override
public void run() {
long a = 0l;
for (long i = 0; i < COUNT; i++) {
a++;
}
System.out.println("线程1结束");
}
});
Thread t2 = new Thread() {
@Override
public void run() {
long b = 0l;
for (long i = 0; i < COUNT; i++) {
b++;
}
System.out.println("线程2结束");
}
};
//启动线程
t1.start();
t2.start();
//等待线程执行完成
try {
t1.join();
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
try {
t2.join();
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
long end = System.currentTimeMillis();
System.out.println("并行总耗时"+(end - start));
}
结果显示:
并行的结果比串行的时间短,但又不是串行的二分之一
这说明每创建一个线程都是要消耗时间和资源的
当我们把计算次数改到一万的计算量时:
可以看到串行比并行块
所以并不是所有场景使用多线程都可以提高效率的
具体还是要根据计算量来确定
3.线程的类构造方法
代码展示:
public class Demo07 {
public static void main(String[] args) {
Thread t1 = new Thread(new Runnable() {
@Override
public void run() {
System.out.println("Runnable!!!"+Thread.currentThread().getName());
}
},"Runnable创建的一个线程");
Thread t2 = new Thread("Thread创建的线程") {
@Override
public void run() {
System.out.println("Thread!!!"+Thread.currentThread().getName());
}
};
Thread t3 = new Thread(() -> {
System.out.println("lambda!!"+Thread.currentThread().getName());
},"lambda创建的线程");
t1.start();
t2.start();
t3.start();
}
}
4.Thread类的常见属性
1.演示各个属性
2.演示后台线程
在线程启动之前设置
当把线程设置为后台线程之后(守护线程),当main方法结束之后,线程会自动结束
生活中设置业务的线程几乎都是前台线程
处理一些数据不太重要的,容错率较高的业务或辅助业务
3.演示线程是否存活
isAlive()指的是系统的线程(PCB)是否存活,并不是我们创建出来的Thread对象
4.线程中断
停止或中断当前线程的任务
1.通过是否中断的标志位
public class Demo10_Interrupted01 {
private static boolean isQuit = false;
public static void main(String[] args) throws InterruptedException{
Thread thread = new Thread(() -> {
while (!isQuit) {
System.out.println("线程~~~~");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println("线程任务结束");
});
//启动线程
thread.start();
//主线程休眠三秒,模拟子线程正在执行任务
Thread.sleep(3000);
// 设置中断标志位为true
isQuit = true;
//让子线程先结束
Thread.sleep(1000);
System.out.println("主线程结束");
}
}
2. 通过调用Thread类提供的interruped()方法来中断线程
当线程在阻塞或者Sleep状态时,调用interruped方法,会中断当前Sleep的休眠状态,并抛出异常,只有当线程在RUUNABLE状态时,才会真正的结束线程
在异常中处理
5.线程等待
Jion()
6.获取当前线程
7.休眠当前线程
Thread.sleep(1000);
面试题:start()和run()方法的区别?
start(),申请一个真正的系统线程
run(),定义线程要执行的任务
1.直接调用run()方法,并不会申请一个真正的系统线程(PCB),只是单纯调用对象的方法
2.调用start()方法,JVM会调用本地方法去系统中真正的申请一个线程(PCB),并执行run()方法中的逻辑
8.线程状态