声明:该专栏本人重新过一遍java知识点时候的笔记汇总,主要是每天的知识点+题解,算是让自己巩固复习,也希望能给初学的朋友们一点帮助,大佬们不喜勿喷(抱拳了老铁!)
往期回顾
Java学习day22:进程和线程、并发并行、线程创建方式(知识点详解)-CSDN博客
Java学习day21:System类、Runtime类、Date类、Calendar类(知识点详解)-CSDN博客
Java学习day20:常用数据类型的包装类、Math类、Random类(知识点详解)-CSDN博客
`Thread()` 分配一个新的 `Thread`对象。 | 无参构造方法 |
`Thread(Runnable target)`分配一个新的 `Thread`对象。 | 有参构造 |
`Thread(Runnable target, String name)`分配一个新的 `Thread`对象。 | 并起名字,省略了调用setname方法那一步 |
(1)
① `static Thread` `currentThread()`
返回对当前正在执行的线程对象的引用,是一个静态方法,直接用Thread类名调用。
(2)
②`String``getName()`
返回此线程的名称。
(3)
③void `setName(String name)`
将此线程的名称更改为等于参数 `name` 。
为什么常用这个方法,这是因为jvm虚拟机会自动给各个线程起名字,当然我们也可以自己起,为了方便我们自己起名字,所以需要用到。
示例:
class MyThread1 implements Runnable {
@Override
public void run() {
Thread thread = Thread.currentThread();
//此时这个thread对象是MyThread1这个线程
//对子线程设置名字
thread.setName("mythread1子线程");
System.out.println(thread.getName());//Thread-0
}
}
class MyThread2 implements Runnable {
@Override
public void run() {
Thread thread = Thread.currentThread();
System.out.println(thread.getName());//狗蛋
}
}
public class Demo1 {
public static void main(String[] args) {
//currentThread() 获取当前线程对象
Thread thread = Thread.currentThread();
//现在thread 这个对象是哪个线程?主线程
//为啥是main主线程
//给main主线程设置名字
thread.setName("主线程");
//获取的是main主线程的名字,Jvm会给主线程还有其他线程一个默认的名字
System.out.println(thread.getName());//main
// MyThread1 myThread1 = new MyThread1();
// Thread thread1 = new Thread( myThread1);
// thread1.start();
new Thread(new MyThread1()).start();
//Java中默认的主线程叫main 子线程叫Thread-0 Thread-1....
//默认的有名字,咱们能不能对线程自定义名字?能
//我在启动MyThread2的这个线程的时候顺便起名字
MyThread2 myThread2 = new MyThread2();
//myThread2线程的名字就叫狗蛋,是在创建线程的时候就已经起好名字了
Thread thread1 = new Thread(myThread2, "狗蛋");
thread1.start();
}
}
(4)
④ int `getPriority()`
返回此线程的优先级。
(5)
⑤void`setPriority(int newPriority)`
更改此线程的优先级。
记住,设置优先并不一定优先,只是增加了执行的概率。最小值是1,最大值是10,默认的是5。
由于线程是抢占式运行,所以即使定了优先级也没法保证顺序,用处不大。
示例:
class MyThread3 implements Runnable {
@Override
public void run() {
//想看一下MyThread3这个线程的优先级是几
Thread thread = Thread.currentThread();
thread.setPriority(10);
System.out.println(thread.getPriority());
for (int i = 0; i < 100; i++) {
System.out.println("MyThread3线程:" + i);
}
}
}
class MyThread4 implements Runnable {
@Override
public void run() {
//想看一下MyThread3这个线程的优先级是几
Thread thread = Thread.currentThread();
thread.setPriority(1);
System.out.println(thread.getPriority());
for (int i = 0; i < 100; i++) {
System.out.println("MyThread4线程:" + i);
}
}
}
public class Demo2 {
public static void main(String[] args) {
//默认的优先级都是5,能不能手动去修改某一个线程的优先级?
//可以
Thread thread = Thread.currentThread();
//主线程的优先级设置1
//thread.setPriority(1);
//获取主线程的优先级
System.out.println(thread.getPriority());//5
//优先级 1 ~10 1的优先级最低 10的优先级最高
//jvm默认线程的优先级是5
// for (int i = 0; i < 100; i++) {
// System.out.println("主线程:" + i);
// }
new Thread(new MyThread3()).start();
new Thread(new MyThread4()).start();
//所以优先级不要用啦!!!并不一定真正的优先!!!
//线程执行的结果不可控!!!很尴尬!!!
}
}
(6)
⑥`static void``sleep(longmillis)`
使当前正在执行的线程以指定的毫秒数暂停(暂时停止执行),具体取决于系统定时器和调度程序的精度和准确性。
也是一个静态方法,直接用Thread类名调用。
示例:
class MyThread5 implements Runnable {
@Override
public void run() {
try {
//发现 Thread.sleep 有一个运行时异常,
//但是发现没有抛出,只有try-catch 为啥?
//sleep方法写在了run方法中了,因为
//run方法是重写的, 父类的 public abstract void run();
//父类有抛出吗?没有抛出,重写是比较严格的
//父类没有抛出,子类也同样不能抛出
Thread.sleep(10000);//10秒
} catch (InterruptedException e) {
e.printStackTrace();
}
for (int i = 0; i < 500; i++) {
System.out.println("MyThread5:" + i);
}
}
}
class MyThread6 implements Runnable {
@Override
public void run() {
for (int i = 0; i < 500; i++) {
System.out.println("MyThread6:" + i);
}
}
}
public class Demo3 {
public static void main(String[] args) {
new Thread(new MyThread5()).start();
new Thread(new MyThread6()).start();
//发现运行的结果是不可控的,是随机的抢占式的
//咱们接下来学习一个东西叫sleep 让某一个线程睡一会儿
//这个线程在睡觉的期间不会去抢占cpu 不执行
//现在我让MyTread5睡了一会儿。就意味着绝对MyThread6线程先执行
//实现可控的效果
//思考:sleep方法再开发的时候敢用不敢用?
//不敢用。睡多久你知道吗?睡多久合适?不能确定
//cpu最大利用化。不可能让cpu闲置
//如果sleep睡眠时间少的话,还是抢占
//如果sleep睡眠你时间太长的话,就会cpu就会闲置
//没有办法把控的!!! 接下来要学习锁!!!
}
}
发现Thread.sleep有一个运行时异常,但是发现没有抛出,只有try-catch为啥?sleep方法写在了run方法中了,因为run方法是重写的,父类的publicabstractvoidrun();父类有抛出吗?没有抛出,重写是比较严格的父类没有抛出,子类也同样不能抛出,如果放在main方法里就会抛出。
本身线程抢占式运行,结果是不可控的,但是用sleep方法可以保证其不去抢占cpu,这样就保证了结果的可控性,但是实际开发又是绝对不可以用的,睡多久你知道吗?睡多久合适?不能确定cpu最大利用化。不可能让cpu闲置 。
如果sleep睡眠时间少的话,还是抢占,如果sleep睡眠时间太长的话,就会cpu就会闲置。
1.新建线程的两种方式
1.继承Thread
2.实现Runnable接口【开发要用的】
代码要自己学会写的!!!
2.线程的方法
Thread.currentThread();获取当前线程对象
setPriority();设置优先级的
getPriority(); 获取当前线程的优先级
getName();得到线程的名字
setName();设置线程的名字
sleep();线程的休眠
以上,就是今天的所有知识点了。线程方法比较多而且都很重要,大家得多花点时间,静下心看代码,写代码,多理解,多运用,重点是多去运用。
加油吧,预祝大家变得更强!