线程的常见方法
1.1设置和获取线程名称【应用】
- 创建线程
public class Mythread extends Thread {
@Override
public void run() {
for (int i = 0; i < 100; i++) {
System.out.println(getName()+"------------"+i);
}
}
}
- 线程有默认的名字,查看线程的默认名字
线程对象.getName()方法
public class Demo {
public static void main(String[] args) {
//线程有默认的名字,格式: Thread-编号
Mythread t1 = new Mythread();
Mythread t2 = new Mythread();
//getName获取线程的名字
System.out.println(t1.getName());
System.out.println(t2.getName());
}
}
- 结果:
- 设置线程的名字
线程对象.setName(“线程名字”)
public class Demo {
public static void main(String[] args) {
//线程有默认的名字,格式: Thread-编号
Mythread t1 = new Mythread();
//构造方法设置名字,需要在MyThread中添加构造方法
Mythread t2 = new Mythread();
//set方式设置名字
t1.setName("名字1");
t2.setName("名字2");
t1.start();
t2.start();
}
}
- 运行结果
- 构造方法设置线程名字
添加构造方法
public class Mythread extends Thread {
//添加构造方法,设置线程名称
public Mythread() {
}
public Mythread(String name) {
super(name);
}
@Override
public void run() {
for (int i = 0; i < 100; i++) {
System.out.println(getName()+"------------"+i);
}
}
}
- 设置名字
public class Demo {
public static void main(String[] args) {
//构造方法设置名字,需要在MyThread中添加构造方法
Mythread t1 = new Mythread("名字1");
t1.start();
}
}
- 结果
1.2获取当前线程对象
- 获取当前main方法的线程对象
Thread.currentThread()
public class Demo {
public static void main(String[] args) {
//通过Thread的静态方法currentThread()获取当前对象
//哪个线程执行到这个方法,就会获取当前线程的对象
//可以在第二种创建线程的方法中调用,获取线程的名称
Thread thread = Thread.currentThread();
//获取名称
String name = thread.getName();
System.out.println(name);
}
}
- 运行结果
main方法的线程名称为main
- 可以在实现Callable接口和Runable接口的创建方式中获取线程对象,在可以获取线程名称等
1.3线程休眠【应用】
- 方法
Thred.sleep() 毫秒
main方法中:
public class Demo {
public static void main(String[] args) throws InterruptedException {
System.out.println("睡觉前");
Thread.sleep(3000);
System.out.println("睡醒了");
}
}
- 运行结果
1.4线程优先级【应用】
-
线程调度
-
两种调度方式
- 分时调度模型:所有线程轮流使用 CPU 的使用权,平均分配每个线程占用 CPU 的时间片
- 抢占式调度模型:优先让优先级高的线程使用 CPU,如果线程的优先级相同,那么会随机选择一个,优先级高的线程获取的 CPU 时间片相对多一些
-
Java使用的是抢占式调度模型
-
随机性
假如计算机只有一个 CPU,那么 CPU 在某一个时刻只能执行一条指令,线程只有得到CPU时间片,也就是使用权,才可以执行指令。所以说多线程程序的执行是有随机性,因为谁抢到CPU的使用权是不一定的
-
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 "线程执行完毕了";
}
}
public class Demo {
public static void main(String[] args) {
//线程优先级:1-10 默认值 5
//线程的优先级越高表示抢到CPU执行权的概率越高
//开启一条线程
MyCallable myCallable = new MyCallable();
FutureTask<String> futureTask = new FutureTask<>(myCallable);
Thread thread = new Thread(futureTask);
thread.setName("飞机");
thread.setPriority(10);
System.out.println(thread.getPriority());
thread.start();
//开启第二条线程
MyCallable myCallable2 = new MyCallable();
FutureTask<String> futureTask2 = new FutureTask<>(myCallable2);
Thread thread2 = new Thread(futureTask2);
thread2.setPriority(1);
System.out.println(thread2.getPriority());
thread2.setName("坦克");
thread2.start();
}
}
- 运行结果
线程优先级:1-10 默认值 5
线程的优先级越高表示抢到CPU执行权的概率越高
1.5守护线程【应用】
- 相关方法
void setDaemon(boolean on)
将此线程标记为守护线程,当运行的线程都是守护线程时,Java虚拟机将退出 - 理解
可以把360软件当成一个线程,360中的杀毒也当成一个线程,如果先运行杀毒的功能,则再关闭360软件后则杀毒的功能也将停止.杀毒就相当于一个守护线程,守护着整个360软件. - 创建两个线程
public class Mythread extends Thread {
@Override
public void run() {
for (int i = 0; i < 10; i++) {
System.out.println(Thread.currentThread().getName()+"======"+i);
}
}
}
public class Mythread2 extends Thread {
@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) {
Mythread mythread = new Mythread();
mythread.setName("主线程");
mythread.start();
Mythread2 mythread2 = new Mythread2();
mythread2.setName("守护线程");
//第二个线程设置为守护线程
//当普通线程执行完毕后,守护线程就么有执行下去的必要了
mythread2.setDaemon(true);
mythread2.start();
}
}
-运行结果
- 守护线程不会立刻停止,还会运行一点点