1、进程:
2、线程:
3、线程的生命周期:
测试代码1:
package test.thread;
//用Thread创建3个线程
public class ThreadDemo {
// 计算0~100的整数和
static class SumTask implements Runnable {
@Override
public void run() {
int sum = 0;
for (int i = 0; i <= 100; i++) {
sum += i;
}
System.out.println("Sum of 0 to 100: " + sum);
}
}
// 计算0~8的阶乘
static class FactorialTask implements Runnable {
@Override
public void run() {
long factorial = 1;
for (int i = 1; i <= 8; i++) {
factorial *= i;
}
System.out.println("Factorial of 8: " + factorial);
}
}
// 计算0~10的数的平方和
static class SquareSumTask implements Runnable {
@Override
public void run() {
int sum = 0;
for (int i = 0; i <= 10; i++) {
sum += i * i;
}
System.out.println("Sum of squares of 0 to 10: " + sum);
}
}
public static void main(String[] args) {
// 创建并启动第一个线程
Thread sumThread = new Thread(new SumTask(), "SumCalculator");
sumThread.start();
// 创建并启动第二个线程
Thread factorialThread = new Thread(new FactorialTask(), "FactorialCalculator");
factorialThread.start();
// 创建并启动第三个线程
Thread squareSumThread = new Thread(new SquareSumTask(), "SquareSumCalculator");
squareSumThread.start();
}
}
测试代码2:
package test.thread;
public class ThreadLifecycleDemo {
public static void main(String[] args) {
// 第一个线程计算0~100的整数和
Thread sumThread = new Thread(() -> {
System.out.println("线程1开始计算0~100的整数和...");
try {
Thread.sleep(1000); // 耗时操作,线程阻塞
} catch (InterruptedException e) {
e.printStackTrace();
}
int sum = 0;
for (int i = 0; i <= 100; i++) {
sum += i;
}
System.out.println("线程1计算完成,0~100的整数和是: " + sum);
});
// 第二个线程计算0~8的阶乘
Thread factorialThread = new Thread(() -> {
System.out.println("线程2开始计算0~8的阶乘...");
try {
Thread.sleep(300); // 耗时操作,线程阻塞
} catch (InterruptedException e) {
e.printStackTrace();
}
long factorial = 1;
for (int i = 1; i <= 8; i++) {
factorial *= i;
}
System.out.println("线程2计算完成,0~8的阶乘是: " + factorial);
});
// 第三个线程计算0~10的平方和
Thread squareSumThread = new Thread(() -> {
System.out.println("线程3开始计算0~10的平方和...");
try {
Thread.sleep(2000); // 耗时操作,线程阻塞
} catch (InterruptedException e) {
e.printStackTrace();
}
int sum = 0;
for (int i = 0; i <= 10; i++) {
sum += i * i;
}
System.out.println("线程3计算完成,0~10的平方和是: " + sum);
});
// 启动所有线程
sumThread.start();
factorialThread.start();
squareSumThread.start();
}
}
测试代码3:
package test.thread;
//抢占式线程执行的随机性
public class ThreadMethodsDemo {
// 计算阶乘
private static long factorial(int n) {
long result = 1;
for (int i = 2; i <= n; i++) {
result *= i;
}
return result;
}
public static void main(String[] args) {
// 创建Thread对象来执行累加任务
Thread myThread = new Thread(() -> {
int sum = 0;
for (int i = 0; i <= 100; i++) {
sum += i;
}
System.out.println("Finished summation in thread: " + Thread.currentThread().getName() + " with result: " + sum);
});
// 设置线程的名称
myThread.setName("SummationThread");
// 启动线程
myThread.start();
// 主线程执行0到10的阶乘计算
long factorialResult = 1;
for (int i = 0; i <= 8; i++) {
factorialResult = factorial(i);
System.out.println("Factorial of " + i + " in main thread: " + factorialResult);
}
// 等待子线程完成
try {
myThread.join();
} catch (InterruptedException e) {
Thread.currentThread().interrupt(); // 保持中断状态
System.err.println("Main thread was interrupted while waiting for SummationThread to finish.");
}
}
}
测试代码4:
package test.thread;
//使用线程优先级设置,并不能保证线程的有序调度。
public class ThreadPriorityDemo {
// 第一个线程任务:计算0~100的整数和
static class SumTask extends Thread {
public void run() {
int sum = 0;
for (int i = 0; i <= 100; i++) {
sum += i;
}
System.out.println("Sum of 0 to 100: " + sum + " by " + Thread.currentThread().getName() + " with priority " + Thread.currentThread().getPriority());
}
}
// 第二个线程任务:计算0~8的阶乘
static class FactorialTask extends Thread {
public void run() {
long factorial = 1;
for (int i = 1; i <= 8; i++) {
factorial *= i;
}
System.out.println("Factorial of 8: " + factorial + " by " + Thread.currentThread().getName() + " with priority " + Thread.currentThread().getPriority());
}
}
// 第三个线程任务:计算0~10的数的平方和
static class SquareSumTask extends Thread {
public void run() {
int sum = 0;
for (int i = 0; i <= 10; i++) {
sum += i * i;
}
System.out.println("Sum of squares of 0 to 10: " + sum + " by " + Thread.currentThread().getName() + " with priority " + Thread.currentThread().getPriority());
}
}
public static void main(String[] args) {
// 创建线程实例
SumTask task1 = new SumTask();
task1.setName("Task1");
task1.setPriority(Thread.MAX_PRIORITY); // 设置最高优先级,最高优先级为10。
FactorialTask task2 = new FactorialTask();
task2.setName("Task2");
task2.setPriority(Thread.NORM_PRIORITY + 1); // 设置中等偏上优先级 ,默认优先级为5,+1为6。
SquareSumTask task3 = new SquareSumTask();
task3.setName("Task3");
task3.setPriority(Thread.MIN_PRIORITY); // 设置最低优先级,最低优先级为1。
// 启动线程
task1.start();
task2.start();
task3.start();
// 线程调度的不可预测,并不能保证输出顺序与线程启动顺序一致。
}
}
测试代码5:
package test.thread;
//线程调度,使用join()方法控制线程的执行循序。
public class OrderedThreadExecution {
// 第一个线程任务:计算0~100的整数和
static class SumTask extends Thread {
@Override
public void run() {
int sum = 0;
for (int i = 0; i <= 100; i++) {
sum += i;
}
System.out.println("Sum of 0 to 100: " + sum);
}
}
// 第二个线程任务:计算0~8的阶乘
static class FactorialTask extends Thread {
@Override
public void run() {
long factorial = 1;
for (int i = 1; i <= 8; i++) {
factorial *= i;
}
System.out.println("Factorial of 8: " + factorial);
}
}
// 第三个线程任务:计算0~10的数的平方和
static class SquareSumTask extends Thread {
@Override
public void run() {
int sum = 0;
for (int i = 0; i <= 10; i++) {
sum += i * i;
}
System.out.println("Sum of squares of 0 to 10: " + sum);
}
}
public static void main(String[] args) {
// 创建线程实例
SumTask task1 = new SumTask();
FactorialTask task2 = new FactorialTask();
SquareSumTask task3 = new SquareSumTask();
// 启动第一个线程
task1.start();
// 等待第一个线程完成
try {
task1.join();
} catch (InterruptedException e) {
Thread.currentThread().interrupt(); // 保持中断状态
System.err.println("First thread was interrupted.");
return;
}
// 启动第二个线程
task2.start();
// 等待第二个线程完成
try {
task2.join();
} catch (InterruptedException e) {
Thread.currentThread().interrupt(); // 保持中断状态
System.err.println("Second thread was interrupted.");
return;
}
// 启动第三个线程
task3.start();
// 这里没有等待第三个线程完成,因为main方法会在所有非守护线程完成后自动结束
// 如果需要等待第三个线程完成,可以添加task3.join();
// 主线程继续执行其他任务
}
}
4、守护线程:
测试代码1:
package test.thread;
//创建一个守护线程,在后台不断输出消息,
//主线程在5秒后结束,从而导致守护线程自动结束。
public class DaemonThreadTest {
public static void main(String[] args) {
// 创建守护线程
Thread daemonThread = new Thread(new Runnable() {
@Override
public void run() {
while (true) {
System.out.println("守护线程正在运行...");
try {
Thread.sleep(1000); // 暂停1秒
} catch (InterruptedException e) {
System.out.println("守护线程被中断");
}
}
}
});
// 设置该线程为守护线程
// daemonThread.setDaemon(true);
// 如果不设置为守护线程,主线程运行结束后,子线程任然运行,且不会停,因为是死循环。
// 启动守护线程
daemonThread.start();
// 主线程休眠5秒
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("主线程结束");
// 当主线程结束时,守护线程会被自动终止
}
}
运行结果如下:
测试代码2:
package test.thread;
//守护线程的主要作用:
//资源清理:守护线程可以负责清理由其他线程产生的临时文件、内存缓存或其他类型的资源。清理任务在JVM退出时不是必须完成的,但如果能够完成,则可以减少资源泄露和潜在的问题。
//日志记录:守护线程可以用于记录程序的运行日志,包括错误、警告、调试信息等。日志对于程序的调试、监控和性能分析非常重要。由于守护线程在JVM退出时会自动停止,不需要担心它们会阻止JVM的正常退出。
//状态监控:守护线程可以定期检查程序的运行状态,如内存使用情况、线程活动、系统资源等。如果发现异常情况,守护线程可以采取适当的措施,如记录日志、发送警报或尝试恢复。
//定时任务:Timer和ScheduledExecutorService通常用于执行定时任务,但守护线程也可以用于此目的。守护线程可以定期检查某个条件,并在满足条件时执行特定的任务。
//垃圾收集Java的垃圾收集器(GC)是由JVM自动管理的,并且不是由程序员直接创建的,它可以视为守护线程的一个例子。GC线程负责清理不再被使用的对象,以释放内存空间。
//这些线程在JVM运行时自动运行,并且在JVM退出时自动停止。
//提升响应性:将非关键的耗时任务交给守护线程处理,主线程(通常是用户线程)可以更快地响应用户请求或执行其他关键任务
//守护线程在JVM退出时会自动停止,不应该执行任何必须在JVM退出前完成的关键任务。
//如果程序需要在JVM退出前完成某些任务(如关闭数据库连接、释放资源等),则应该使用非守护线程来成这些任务,并确保在JVM退出前能正确完成。
//JVM中只剩下守护线程时,JVM会立即退出,而不会等待守护线程完成。
public class DaemonThreadExample {
public static void main(String[] args) {
// 创建并启动非守护线程
Thread nonDaemonThread = new Thread(() -> {
System.out.println("非守护线程开始执行...");
try {
// 耗时操作
Thread.sleep(100000); // 休眠100秒
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("非守护线程执行完成。");
});
nonDaemonThread.start();
// 创建并启动守护线程
Thread daemonThread = new Thread(() -> {
int i = 0;
while (true) {
System.out.println("守护线程正在执行迭代: " + i++);
try {
// 耗时操作比非守护线程短
Thread.sleep(1000); // 休眠1秒
} catch (InterruptedException e) {
e.printStackTrace();
break; // 中断时退出循环
}
}
});
daemonThread.setDaemon(true); // 设置为守护线程
daemonThread.start();
// 主线程结束,由于非守护线程仍在运行,JVM会等待它
System.out.println("主线程结束。");
// 由于main方法已经执行完毕,如果没有非守护线程,JVM会立即退出。
// 非守护线程会阻止JVM退出,直到它完成。
}
}
运行结果如下: