Java多线程编程(二)——线程的常见方法
使用getName()获取线程的名字
线程是有默认名字的,格式为 :Thread-编号
我们可以进入Thread类中查看一下源码
选中Thread ,ctrl + B
再使用 Alt + 7,开启骨架
选择Thread() 的空参构造方法
public Thread() {
this((ThreadGroup)null, (Runnable)null, "Thread-" + nextThreadNum(), 0L);
}
getName()方法的使用
@Override
public void run() {
for (int i = 0; i < 100; i++) {
//Thread时有默认名字的!
System.out.println(getName() + "@@@" + i);
}
}
Thread类中设置线程的名字
1.setName()更改线程的名字
MyThread T1 = new MyThread();
T1.setName("第一条线程");
2.通过构造方法更改线程的名字
初学者常见错误——“直接在MyThread中填入参数”
即:MyThread T1 = new MyThread(“第一条线程”);
错误原因:
我们创建的不是Thread类对象,而是其子类的对象MyThrad,在其子类中我们没有写带参构造方法,虽然他们有继承关系,But构造方法只能被子类使用super关键字去调用。
正确写法:
package 多线程.ThreadDemo04;
//ctrl + B 进入Thread类中查看源码
//Alt + 7 导出项目类的骨架
//Alt + Insert 打开Generate
public class MyThread extends Thread{
/**
* 我们创建的不是Thread对象,而是Thread的子类对象MyThread
* 在其子类MyThread中没有带参构造
* 构造方法只能被子类用 super 关键字调用!!!
*/
public MyThread() {
}
public MyThread(String name) {
super(name);
}
@Override
public void run() {
for (int i = 0; i < 100; i++) {
//Thread时有默认名字的!
System.out.println(getName() + "@@@" + i);
}
}
}
package 多线程.ThreadDemo04;
//ctrl + B 进入Thread类中查看源码
//Alt + 7 导出项目类的骨架
//Alt + Insert 打开Generate
public class MyThread extends Thread{
/**
* 我们创建的不是Thread对象,而是Thread的子类对象MyThread
* 在其子类MyThread中没有带参构造
* 构造方法只能被子类用 super 关键字调用!!!
*/
public MyThread() {
}
public MyThread(String name) {
super(name);
}
@Override
public void run() {
for (int i = 0; i < 100; i++) {
//Thread时有默认名字的!
System.out.println(getName() + "@@@" + i);
}
}
}
获取当前线程的对象
public static Thread currentThread() : 返回当前正在执行的线程对象的引用
比如在Runnable中,想要使用getName()方法,不能直接使用getName() 方法,这是因为MyRunnable没有继承Thread。
但是我们可以使用Thread.currentThread()先获取当前线程的对象,再调用getName()方法即可。
public class MyRunnable implements Runnable {
@Override
public void run() {
for (int i = 0; i < 100; i++) {
System.out.println(Thread.currentThread().getName() + "---" + i);
}
}
}
线程的休眠
public class Demo {
public static void main(String[] args) throws InterruptedException {
Thread.sleep(3000);
System.out.println("3秒后打印!");
}
}
注意此处的异常抛出!
在Runnable中使用sleep()有一个小细节要注意:
public class MyRunnable implements Runnable {
@Override
public void run() {
for (int i = 0; i < 100; i++) {
/**
* 如果一个类 or 接口中的方法没有抛出异常
* 那么他的子类 or 实现类 就不可以抛出异常!
* 只能使用 try-catch
*/
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + "---" + i);
}
}
}
这里异常的抛出是用了try-catch的方式,我们可以ctrl + B 进入Runnable接口中看看
如果一个类 or 接口 他们的方法没有抛出异常,那么他们的子类重写此方法时就不可以抛出异常,只能使用try-catch。
线程的优先级
线程调度
两种调度方式
分时调度模型:所有线程轮流使用 CPU 的使用权,平均分配每个线程占用 CPU 的时间片
抢占式调度模型:优先让优先级高的线程使用 CPU,如果线程的优先级相同,那么会随机选择一个,优先级高的线程获取的 CPU 时间片相对多一些
Java使用的是抢占式调度模型
随机性
假如计算机只有一个 CPU,那么 CPU 在某一个时刻只能执行一条指令,线程只有得到CPU时间片,也就是使用权,才可以执行指令。所以说多线程程序的执行是有随机性,因为谁抢到CPU的使用权是不一定的
关于线程调度这一块的内容没法详细说,不懂的可以看看王道的视频
关于优先级的常见方法
方法名 | 说明 |
---|---|
final int getPriority() | 返回此线程的优先级 //默认是5 |
final void setPriority(int newPriority) | 更改此线程的优先级线程默认优先级是5;线程优先级的范围是:1-10 |
Coding:
public class Demo {
public static void main(String[] args) {
//优先级: 1 - 10 默认值:5
MyCallable mc = new MyCallable();
FutureTask<String> ft = new FutureTask<>(mc);
Thread t1 = new Thread(ft);
t1.setName("火箭");
//不设置默认优先级是 5
System.out.println(t1.getPriority());
t1.start();
MyCallable mc2 = new MyCallable();
FutureTask<String> ft2 = new FutureTask<>(mc2);
Thread t2 = new Thread(ft2);
t2.setName("飞机");
//设置优先级为 10
t2.setPriority(10);
t2.start();
}
}
public class MyCallable implements Callable<String> {
@Override
public String call() throws Exception {
for (int i = 0; i < 100; i++) {
System.out.println(Thread.currentThread().getName() + "---" + i);
}
return "线程执行完毕了";
}
}
注意:线程的优先级越大,是指线程抢到CPU资源的几率更大,而不是说优先级高的线程必然先执行!
守护线程\后台线程
任何一个守护线程都是整个JVM中所有非守护线程的保姆;
守护线程类似于整个进程的一个默默无闻的小喽啰;它的生死无关重要,它却依赖整个进程而运行;哪天其他线程结束了,没有要执行了,程序就结束了,理都没理守护线程,就把它中断了;
方法名 | 说明 |
---|---|
void setDaemon(boolean on) | 将此线程标记为守护线程,当运行的线程都是守护线程时,Java虚拟机将退出 |
把将线程设置为守护线程,当普通线程执行完之后,那么守护线程也没有继续运行下去的必要了。
但是不会立马停止,由于CPU运行速度很快,守护线程还是会再“挣扎一会”!然后停止。
在Coding中注意:守护线程不能持有任何需要关闭的资源,例如打开文件等,因为虚拟机退出时,守护线程没有任何机会来关闭文件,这会导致数据丢失。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 全程不用写代码,我用AI程序员写了一个飞机大战
· DeepSeek 开源周回顾「GitHub 热点速览」
· 记一次.NET内存居高不下排查解决与启示
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· .NET10 - 预览版1新功能体验(一)