首先:线程与进程的区别是什么呢?
进程:正在运行的一个程序称之为一个进程,进程负责了内存空间的划分,从宏观的角度:windows是在同时执行多个程序
从微观的角度看,CPU是在快速的切换要执行的程序。实质上,一个时间片上只有一个程序在执行。
线程:线程负责了代码的执行,就是进程中的执行路径。
多线程:在一个进程中有多个线程同时在执行不同的任务
疑问1:线程负责了代码的执行,我们之前没使用线程为什么代码可以执行?
答:JVM在运行的时候会自动创建一个main线程执行main方法中的代码。
疑问2:一个JAVA程序至少需要几个线程?
答:至少需要2个线程,一个是主线程负责main方法的代码,另外一个是垃圾回收器的线程负责回收垃圾。
多线程的好处:1.解决了一个程序能够执行多个任务的问题
2.多线程并没有提高效率 而是提高了资源的利通率。
多线程的弊端:
1.增加了CPU的负担
2.容易引发线程安全问题
3.出现了死锁的现象
那么我们如何创建多线程呢?
方式1:继承Thread类,并重写run()方法,并将自定义线程的任务代码写在run方法里。创建继承自Thread类的对象,然后调用start()方法开启线程。
方式2:实现Runnable接口,并实现run()方法。将自定义线程的任务代码写在run()方法里。创建实现Runnable接口的类的对象,然后将对象作为实参传递给Thread方法创建线程对象,然后调用start()方法开启线程。
疑问:为什么要重写run方法,重写run方法的目的?
答:每个线程都有自己的任务代码,jvm创建的主线程任务代码就是main方法中的所有代码,自定义线程的任务代码就写在run方法中,自定义线程负责了run方法中的代码
注意: run方法不能直接调用,直接调用run方法就相当于调用了一个普通的方法而已,并没有开启新的线程
问题1:请问Runnable实现类的对象是线程对象吗?
Runnable实现类的对象并不是线程对象,只不过实现了Runnable接口的对象而已
只有Thread或者Thread子类才能是线程对象 线程都有start方法开启线程
问题2:为什么要把Runnable实现类的对象作为实参传递给Thread对象?作用是什么?
Thread类使用target变量记录了t1对象
源码:public void run() {
if (target != null) {
target.run(); //将Runnable实现类的run方法作为线程对象的run方法
}
}
推荐使用第二种方式创建自定义线程:因为java是单继承多实现的
线程常用的方法:
Thread(String name) 初始化线程的名字
getName() 返回线程的名字
setName(String name) 设置线程对象名
sleep() 线程睡眠指定的毫秒数。是一个静态的方法,哪个线程执行了sleep方法那么就是哪个线程睡眠
为什么sleep不能抛出异常,只能捕获?
答:子类在重写Thread的run()方法,方法重写时子类抛出的异常类型要小于或者等于父类的异常类型。
Thread中run()没有抛出异常,所以子类也不能抛出异常。所以不能直接把异常抛出所以采用捕获的方法
currentThread() 返回当前CPU正在执行的线程的对象 哪个线程执行的 就返回哪个线程的对象
getPriority() 返回当前线程对象的优先级 默认线程的优先级是5 优先级数字越大的 执行的概率越高
setPriority(int newPriority) 设置线程的优先级 虽然设置了线程的优先级,但是具体的实现取决于底层的操作系统的实现(最大的优先级是10 ,最小的1 , 默认是5)。