创建的线程的方式
官方说明创建线程有两种方式:继承Thread类或实现Runnable接口
// 1.继承Thread类
public class MyThread extends Thread{
// 重写run()
@Override
public void run() {
System.out.println("run MyThread");
}
// 创建MyThread执行start()
public static void main(String[] args) {
MyThread myThread = new MyThread();
myThread.start();
}
}
// 2.实现Runnable接口
public class MyRunnable implements Runnable{
// 重写run方法
@Override
public void run() {
System.out.println("run Runnable");
}
// 创建Thread执行start
public static void main(String[] args) {
Thread thread = new Thread(new MyRunnable());
thread.start();
}
}
// Runnable方式变种一:可以使用lambda表达式
public static void main(String[] args) {
new Thread(()->{
System.out.println("lambda run");
}).start();
}
// Runnable方式变种二:如果需要返回值,可以使用callable
public class MyCallable implements Callable<String> {
@Override
public String call() throws Exception {
return "MyCallable";
}
public static void main(String[] args) throws Exception{
Callable<String> myCallable = new MyCallable();
String result = myCallable.call();
System.out.println( result);
}
}
// 另外创建线程当然也可以借助线程池
Thread生命状态
新建(New):线程被创建,但尚未开始行。
运行(Runnable):线程正在执行其任务。
阻塞(Blocked):线程被阻塞,等待某些条件的满足。
等待(Waiting):线程进入无限期等待状态,等待其他线程的通知。
超时等待(Timed Waiting):线程等待一定时间后自动恢复。
终止(Terminated):线程执行完毕或因异常终止。
Thread常用方法
start()
start() 方法将新建的线程切换到就绪状态,等待获取CPU时间片来运行。
run()
在调用 start() 启动线程后,线程将执行其 run() 方法中的代码。
sleep()
用于使线程休眠指定的时间,不会释放锁.
public static void main(String[] args) {
new Thread(()->{
System.out.println(System.currentTimeMillis());
try {
// 睡眠一秒
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(System.currentTimeMillis());
}).start();
}
wait()
用于使线程进入等待状态(会释放锁),通常在同步块中使用,线程等待某个条件满足时被唤醒。
public static void main(String[] args) {
Object lock = new Object();
Thread thread1 = new Thread(() -> {
synchronized (lock) {
try {
lock.wait(); // 线程1等待锁被其他线程唤醒
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("Thread 1 is running");
}
});
Thread thread2 = new Thread(() -> {
synchronized (lock) {
System.out.println("Thread 2 is running");
lock.notify(); // 唤醒等待中的线程1
}
});
thread1.start();
thread2.start();
}
join()
用于等待一个线程结束。调用 join() 的线程将会等待指定线程执行完成后再继续执行.
public static void main(String[] args) {
Thread thread1 = new Thread(() -> {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("Thread 1 is running");
});
Thread thread2 = new Thread(() -> {
System.out.println("Thread 2 is running");
});
thread1.start();
thread2.start();
try {
thread1.join(); // 主线程等待thread1执行完成
thread2.join(); // 主线程等待thread2执行完成
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("thread1&thread2 done");
}
notify() 和 notifyAll()
用于唤醒等待中的线程。notify() 唤醒一个等待线程,而 notifyAll() 唤醒所有等待线程。
// 见wait()示例
yield()
用于提示线程调度器放弃当前线程的 CPU 时间片,使其他线程有机会执行。但是不会释放锁.
public static void main(String[] args) {
Thread thread1 = new Thread(() -> {
for (int i = 0; i < 5; i++) {
System.out.println("Thread 1 - Iteration " + i);
Thread.yield(); // 放弃 CPU 时间片
}
});
Thread thread2 = new Thread(() -> {
for (int i = 0; i < 5; i++) {
System.out.println("Thread 2 - Iteration " + i);
Thread.yield(); // 放弃 CPU 时间片
}
});
thread1.start();
thread2.start();
}
interrupt()
用于中断线程。当一个线程被中断时,它会抛出 InterruptedException 异常.
public static void main(String[] args) {
Thread thread = new Thread(() -> {
while (!Thread.currentThread().isInterrupted()) {
// 执行一些任务
System.out.println("doSomething");
}
});
thread.start();
// 在某个时刻中断线程
thread.interrupt();
}
isInterrupted() 和 interrupted()
isInterrupted() 用于检查线程是否被中断,返回 true 或 false;
interrupted() 用于检查当前线程是否被中断,同时会清除中断状态。
Thread thread = new Thread(() -> {
while (!Thread.currentThread().isInterrupted()) {
// 执行一些任务
System.out.println("doSomething");
}
});
thread.start();
// 在某个时刻中断线程
thread.interrupt();
boolean isInterrupted = thread.isInterrupted(); // 返回 true
boolean interrupted = Thread.interrupted(); // 返回 true,并清除中断状态
System.out.println(isInterrupted);
System.out.println(interrupted);
守护线程
守护线程(Daemon Thread)是在Java中的一种特殊类型的线程,其特点是在后台默默地执行任务,而不会阻止程序的终止。
守护线程通常用于执行后台任务,一旦所有的非守护线程结束,它们会自动退出,不会阻止程序的终止.例如JVM的GC就是守护线程.
public static void main(String[] args) {
Thread normalThread = new Thread(() -> {
for (int i = 1; i <= 5; i++) {
System.out.println("Normal Thread: " + i);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
Thread daemonThread = new Thread(() -> {
while (true) {
System.out.println("Daemon Thread is running");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
daemonThread.setDaemon(true); // 将daemonThread设置为守护线程
normalThread.start();
daemonThread.start();
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("Main Thread exits");
}