什么是线程?
线程就是进程中的一个执行场景,一个进程可以启动多个线程
使用多线程的可以提高CPU的使用率,不是提高执行速度.
比如一个程序要从本地硬盘中读取和处理文件,假设从硬盘中读取一个文件要6秒,处理一个文件用2秒,如果处理两个文件要16秒
6秒读取文件A
2秒处理文件A
6秒读取文件B
2秒处理文件B
在磁盘读取文件时,CPU是在等待状态,此时CPU是空闲的,一秒钟的时间对于CPU来说可以做非常多的事情,可以利用这段空闲时间去做别的事,来改变一下上面程序的操作顺序;
6秒读取文件A
6秒读取文件B + 2秒处理文件A(利用CPU空闲时间)
2秒处理文件B
这样一共需要14秒就可以完成上面的操作,这里其实是通过提高CPU的利用率来减少了操作时间
可通过下图简单理解下
其实并不是同步运行的,只是CPU切换的速度非常快
线程和线程之间共享堆内存和方法区,栈内存是独立的,每个线程有自己独立的栈
多线程的应用场景
qq多人视频
迅雷同时下载多个文件
并行和并发
并行就是两个或者两个以上的任务同时运行,就是甲任务进行的同时,已任务也在进行.(需要多核CPU)
并发是指两个或两个以上的任务都请求运行,而CPU只能接受一个任务,就把这两个任务安排轮流进行,由于时间间隔较短,使人感觉两个任务都在运行.
多线程的缺点
- 设计复杂
多线程中共享堆内存和方法区,因此里面的一些数据是可以共享的,在设计时要确保数据的准确性 - 资源消耗增多
栈内存是不共享的,如果启用多个线程的话会占用更多的内存
使用多线程可以提高CPU的使用率,但不意味着线程越多越好,在编写程序时需要掌握好一个平衡点,这样才能够体现出多线程的价值
创建多线程的三种方式
- 继承Thread类
//1.自定义一个类,继承java.lang包下的Thread类
Class MyThread extends Thread{
//2.重写run方法
public void run(){
//3.将要在线程中执行的代码编写在run方法中
for(int i=0;i<1000;i++){
System.out.println("素质三连!!!");
}
}
public static void main(String[]args){
//4.创建上面定义类的对象
MyThread mt=new MyThread();
//5.调用start方法启动线程
mt.start();
MyThread mt1=new MyThread();
mt1.start();
for(int i=0;i<1000;i++){
System.out.println("素质三连");
}
}
}
使用Runnable接口
//1.自定义一个类实现java.lang包下的Runnable接口
class MyRunnable implements Runnable{
//2.重写run方法
public void run(){
//3.将要在线程中执行的代码编写在run方法中
for(int i=0;i<1000;i++){
System.out.println("素质三连!!!");
}
}
public static void main(String[]args){
//4.创建上面自定义对象
MyRunnable mr=new MyRunnable();
//5.创建Thread对象并将上面自定义类的对象作为参数传递给Thread 的构造方法
Thread t=new Thread(mr);
//6.调用start方法启动线程
t.start();
for(int i=0;i<1000;i++){
System.out.println("素质三连");
}
}
}