目录
4.Thread(Runnable target, String name)
5.Thread(ThreadGroup group, Runnable target)
前四种的具体使用:
Thread t1 = new Thread(); Thread t2 = new Thread(new MyRunnable()); Thread t3 = new Thread("这是我的名字"); Thread t4 = new Thread(new MyRunnable(), "这是我的名字");
1、2种上一篇文章有讲,此处不再赘述
3.Thread(String name)
public class ThreadDemo10 {
public static void main(String[] args) {
//创建线程并设置线程名
Thread t = new Thread("线程1") {
@Override
public void run() {
//休眠线程
try {
Thread.sleep(60 * 60 * 1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
};
//启动线程
t.start();
}
}
4.Thread(Runnable target, String name)
public class ThreadDemo11 {
public static void main(String[] args) {
//创建线程并设置线程名称
Thread thread = new Thread(new Runnable() {
@Override
public void run() {
try {
//休眠1h
Thread.sleep(60 * 60 * 1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
},"Runnable-Thread");
//启动线程
thread.start();
}
}
5.Thread(ThreadGroup group, Runnable target)
线程分组用途:做一个条件约束,将某些线程放到某个分组里,就可对其进行统一处理,比如用while(group.activeCount() > 0) { }来判断控制这一组里所有线程都执行完后再执行下面的代码。
Java语法层面规定:在写sleep时必须强制处理异常try-catch,因为程序在休眠时可能会被其他线程终结,那么就要把这个异常情况进行拦截。
import java.util.Random;
public class ThreadDemo12 {
public static void main(String[] args) {
//1.创建一个线程分组(女子100米比赛)
ThreadGroup group = new ThreadGroup("thread-group");
//2.定义一个公共的任务(线程的任务)
Runnable runTask = new Runnable() {
@Override
public void run() { //业务(任务)
//生成一个1-3秒的随机数(0-2)+1 -> (1-3)
int num = (1 + new Random().nextInt(3));
try {
//跑了n秒之后到达了终点
Thread.sleep(num * 1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
//得到执行此方法的线程
Thread t = Thread.currentThread();
System.out.println(t.getName() + "——选手到达终点:" + num + "s");
}
};
//3.线程(运动员)
//group参数:将3个线程放到一组group里,就可以对其进行统一处理
//runTask参数:设置任务,可以给每一个线程都new一个Runnable;但因为每个选手其任务都是一样的,可以将任务提出来,将匿名内部类赋值到一个变量上
Thread t1 = new Thread(group, runTask); //创建选手1
Thread t2 = new Thread(group, runTask); //创建选手2
Thread t3 = new Thread(group, runTask); //创建选手3
//开跑
t1.start();
t2.start();
t3.start();
//所以人全部到达终点之后宣布成绩
//也可以写 != 0 , >0 更加贴切
while(group.activeCount() > 0) { //分组里面线程活跃数量如果>0会一直进行while循环,当前的main方法就不会执行到下一行宣布比赛成绩,直到所有人全部到达终点,才会执行下一行宣布成绩
}
System.out.println("宣布比赛成绩");
}
}
java语言特性:在一个线程(main方法开一个main线程)中(没有开启新线程)所有代码都是从上往下执行的,只有执行完了上面的代码才会执行下面的代码。
- 所以如果while没执行完,也就是分组里还有线程没执行完,是不会执行下面宣布成绩的,是阻塞式的。
- 但如果去掉while,会先执行宣布成绩,再是选手到达终点。因为先执行主线程,在主线程中同时启动3个新线程,3个新线程和主线程一起并行执行,相当于3个新线程就是3个新分支了,和主线程没关系了,所以主线程在启动3个新线程后继续往下执行宣布成绩(快),是不会等这3个新线程执行完(慢)再去执行宣布成绩的。3个新线程是同时启动,其执行时间设置了随机数休眠,故其执行结束时间是随机的。
- 如果3个新线程不休眠:加while,无论如何都会是3个新线程达到终点执行完再宣布成绩;若不加while,3个新线程和主线程的执行顺序就是随机的。(前提:二者的业务逻辑难易相当)但大概率还是主线程执行更快,因为主线程不像3个新线程,需要切换、启动CPU资源进行调度才能执行。此时由于主线程打印成绩比3个新线程生成随机数业务逻辑更简单,所以会先执行打印成绩再执行3个新线程达到终点。【多个线程执行都是随机的,因为CPU调度线程是随机的。】
note.js同样写的代码不会从上往下执行,要写在回调函数里。