Java 线程详解及线程与进程的区别
线程和进程的概念
在操作系统中,进程可以被看作是一个执行中的程序,它所占用的内存空间中包含了代码,数据,和系统资源等等。而线程则是进程中的执行单元,进程中可以拥有多个线程。
线程与进程的两个最重要的区别如下:
- 一个进程可以有多个线程,各个线程可以并发执行
- 一个进程内的线程共享该进程所占用的资源
Java 线程的创建和启动
Java 中的线程可以通过 Thread 类来创建和启动。以下为线程的创建和启动示例代码:
public class ThreadExample extends Thread {
public void run() {
System.out.println("线程运行中");
}
public static void main(String[] args) {
ThreadExample thread = new ThreadExample();
thread.start();
}
}
上述代码中,我们先创建了一个继承自 Thread 的线程类 ThreadExample,然后在该线程类中实现了 run 方法。在 run 方法中,我们打印了一句话“线程运行中”。
在 main 方法中,我们创建了一个 ThreadExample 类型的对象 thread,然后通过调用 thread.start() 方法来启动线程。
Java 线程的状态
在 Java 中,线程一共有六种状态:
- NEW:新创建的线程状态,线程还未启动
- RUNNABLE:运行中的线程状态,线程正在执行或等待系统资源,例如 CPU 时间片
- BLOCKED:阻塞中的线程状态,线程正在等待锁的时候被挂起
- WAITING:等待中的线程状态,线程在等待另一个线程释放锁以及等待输入输出之类的操作
- TIMED_WAITING:具有时间限制的等待中线程状态,线程在等待另一个线程释放锁或等待超时
- TERMINATED:已结束的线程状态,线程已经执行完毕并终止
Java 线程的同步
Java 中的线程同步可以使用 synchronized 关键字来实现。以下为同步示例代码:
public class SynchronizedExample implements Runnable {
private int num = 0;
public synchronized void synchronizedMethod() {
for (int i = 0; i < 5; i++) {
System.out.println(Thread.currentThread().getName() + " synchronized num:" + num++);
}
}
public void run() {
String threadName = Thread.currentThread().getName();
if (threadName.equals("A")) {
synchronizedMethod();
}
}
public static void main(String[] args) {
SynchronizedExample runnable = new SynchronizedExample();
Thread threadA = new Thread(runnable, "A");
Thread threadB = new Thread(runnable, "B");
threadA.start();
threadB.start();
}
}
上述代码中,我们创建了一个 SynchronizedExample 类型的对象 runnable,并且创建了两个线程 threadA 和 threadB,并且他们执行的是同一个 runnable 对象上的 run 方法。
在 synchronizedMethod 方法中,我们使用 synchronized 关键字来实现了线程同步,让线程 A 和线程 B 能够依次执行。
Java 线程的异常处理
在开发 Java 线程的时候,我们同样需要考虑异常处理。Java 中线程中出现的异常可以通过 UncaughtExceptionHandler 接口来捕捉处理。以下为异常处理示例代码:
public class ExceptionHandlerExample implements Runnable {
@Override
public void run() {
System.out.println(1 / 0);
}
public static void main(String[] args) {
ExceptionHandlerExample runnable = new ExceptionHandlerExample();
Thread thread = new Thread(runnable);
thread.setUncaughtExceptionHandler(new ExceptionHandler());
thread.start();
}
}
class ExceptionHandler implements Thread.UncaughtExceptionHandler {
@Override
public void uncaughtException(Thread t, Throwable e) {
System.out.println(t.getName() + "发生了异常:" + e);
}
}
在上述代码中,我们创建了一个 ExceptionHandlerExample 类型的对象 runnable,并且创建了一个线程 thread 来运行该对象上的 run 方法。然后我们通过调用 thread.setUncaughtExceptionHandler 方法为该线程设置了异常处理器。
在 ExceptionHandler 类中,我们实现了 UncaughtExceptionHandler 接口来定义了线程异常的处理逻辑。在 uncaughtException 方法中,我们打印了异常信息。
Java 线程池
在 Java 中,线程池可以使用 java.util.concurrent.Executors 工厂类来创建。以下为线程池示例代码:
public class ThreadPoolExample implements Runnable {
public void run() {
System.out.println(Thread.currentThread().getName() + "在运行");
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
ExecutorService pool = Executors.newFixedThreadPool(2);
ThreadPoolExample instance = new ThreadPoolExample();
pool.execute(instance);
pool.execute(instance);
pool.execute(instance);
pool.execute(instance);
pool.execute(instance);
pool.shutdown();
}
}
在上述代码中,我们创建了一个 ThreadPoolExample 类型的对象 instance,并且创建了一个线程池 pool 来运行该对象上的 run 方法。在 main 方法中,我们使用 ExecutorService 类型的变量 pool 调用 Executors 的 newFixedThreadPool 方法来创建一个大小为 2 的线程池。
然后我们使用 execute 方法来提交任务,每次执行都在声明一个 instance 线程对象。最后执行 pool.shutdown() 来关闭线程池。
以上为 Java 线程的基本介绍,希望对您理解 Java 线程有所帮助。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:java 线程详解及线程与进程的区别 - Python技术站