线程的状态
- 创建状态: 创建了线程对象
- 就绪状态: 调用了start()方法,线程进入就绪状态,等待CPU资源。
- 运行状态: 获取了CPU资源。此过程中自动调用run()方法
- 阻塞状态: 被人为挂起或需要运行耗时的输入/输出的操作。调用sleep()、suspend()、wait()等方法也会进入阻塞状态
- 终止状态: run()方法运行结束
常用方法
构造方法与命名
我们可以使用下面这个方法在创建线程的时候对线程进行命名。
public Thread(Runnable target,String name)
也可以在创建线程之后调用setName()方法进行命名。
class MyThread implements Runnable {
private String message;
MyThread(String msg){
this.message = msg;
}
//输出传入的字符串和线程的名称
public void method () {
System.out.println(this.message + Thread.currentThread().getName());
}
@Override
public void run() {
method();
}
}
public class test_thread {
public static void main(String[] args) {
//在创建线程时命名
Runnable myThread1 = new MyThread("线程一");
Thread thread1 = new Thread(myThread1,"thread1");
//在创建线程之后使用setName()命名
Runnable myThread2 = new MyThread("线程二");
Thread thread2 = new Thread(myThread2);
thread2.setName("thread2");
thread1.start();
thread2.start();
}
}
如果没有对线程进行命名,线程将会按照创建线程的顺序自动命名,第一个为Thread-0,第二个是Thread-1……
线程休眠
线程休眠指暂停执行一段时间之后,继续执行。
public static void sleep(long millis) throws InterruptedException
设置线程休眠的毫秒数
public static void sleep(long millis, int nanos) throws InterruptedException
设置线程休眠的毫秒数和纳秒数
public class test_thread {
public static void main(String[] args) {
new Thread(() -> {
for(int i = 1;i <= 5;i++){
long start = System.currentTimeMillis();
System.out.print("【第" + i + "次执行");
if(i % 2 ==0){
try {
Thread.sleep(1000);
} catch (InterruptedException ignored){}
}
long end = System.currentTimeMillis();
System.out.println("耗时:" + (end - start) + "ms】");
}
}).start();
}
}
线程中断
public boolean isInterrupted()
判断线程是否中断,返回布尔值
public void interrupt()
强行中断线程
public class test_thread {
public static void main(String[] args) {
Thread thread = new Thread(() -> {
System.out.println("开始执行");
try {
for (int i = 1; i <= 10; i++) {
System.out.println("【第" + i + "次循环】");
Thread.sleep(1);
}
} catch (InterruptedException e){
System.out.println("线程中断!");
}
});
thread.start();
thread.interrupt();
}
}
线程强制执行
多线程启动之后,多个线程会抢占CPU资源,而在同一个时间只能执行一个线程。
因此在我们需要让某个线程对象优先执行时,我们就需要使用强制执行的方法,使得该线程一直独占资源,直到该线程执行结束,再去执行其他线程。
public final void join() throws InterruptedException
等待该线程终止。
public class test_thread {
public static void main(String[] args) {
Thread thread1 = new Thread(() -> {
for (int i = 1; i <= 5; i++) {
try {
Thread.sleep(100);
} catch (InterruptedException ignored){}
System.out.println("【" + Thread.currentThread().getName() + "的第" + i + "次循环】");
}
}, "线程一");
Thread thread2 = new Thread(() -> {
for (int i = 1; i <= 5; i++) {
if(i == 3){
try {
thread1.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
try {
Thread.sleep(100);
} catch (InterruptedException ignored){}
}
System.out.println("【" + Thread.currentThread().getName() + "的第" + i + "次循环】");
}
}, "Thread-two");
thread1.start();
thread2.start();
}
}
线程礼让
线程礼让指使该线程放弃本次抢占CPU资源。
public static void yield()
public class test_thread {
public static void main(String[] args) {
Thread thread1 = new Thread(() -> {
for (int i = 1; i <= 5; i++) {
try {
Thread.sleep(100);
} catch (InterruptedException ignored) {
}
System.out.println("【" + Thread.currentThread().getName() + "的第" + i + "次循环】");
}
}, "线程一");
Thread thread2 = new Thread(() -> {
for (int i = 1; i <= 5; i++) {
if (i % 2 == 0) {
Thread.yield();
try {
Thread.sleep(100);
} catch (InterruptedException ignored) {
}
}
System.out.println("【" + Thread.currentThread().getName() + "的第" + i + "次循环】");
}
}, "Thread-two");
thread1.start();
thread2.start();
}
}
线程优先级
理论上讲,线程优先级越高,其抢占到执行权的可能性就越大;但这并不意味着优先级高的一定比优先级低的先执行,只是可能性变大了。
我们可以设置和获取线程的优先级:
- 设置优先级:public final void setPriority(int newPriority)
- 获取优先级:public final int getPriority()
对于优先级,在Thread类中也提供了常量:
- public static final int MAX_PRIORITY ——最高优先级,其数值为10
- public static final int NORM_PRIORITY ——中等优先级,也是线程的默认优先级,其数值为5
- public static final int MIN_PRIORITY ——最低优先级,其数值为1