JAVA中的线程控制
线程控制是Java并发编程中的核心内容,涉及到线程的创建、同步、通信、调度等多个方面。
一、线程创建与启动 在Java中,创建线程有两种方式:
继承Thread类和实现Runnable接口。
-
继承Thread类 代码例子:
// 继承Thread类
class MyThread extends Thread {@Overridepublic void run() {// 线程执行体System.out.println("线程正在执行");}
}
public class Main {public static void main(String[] args) {MyThread myThread = new MyThread(); // 创建线程对象myThread.start(); // 启动线程}
}
-
实现Runnable接口 代码例子:
// 实现Runnable接口
class MyRunnable implements Runnable {@Overridepublic void run() {// 线程执行体System.out.println("线程正在执行");}
}
public class Main {public static void main(String[] args) {Thread thread = new Thread(new MyRunnable()); // 创建线程对象thread.start(); // 启动线程}
}
二、线程同步
当多个线程访问同一资源时,可能会出现线程安全问题。为了解决这个问题,Java提供了同步机制。
-
使用synchronized关键字 代码例子:
class Counter {private int count = 0;// 同步方法public synchronized void increment() {count++;}public int getCount() {return count;}
}
public class Main {public static void main(String[] args) {Counter counter = new Counter();Thread t1 = new Thread(() -> {for (int i = 0; i < 1000; i++) {counter.increment();}});Thread t2 = new Thread(() -> {for (int i = 0; i < 1000; i++) {counter.increment();}});t1.start();t2.start();try {t1.join();t2.join();} catch (InterruptedException e) {e.printStackTrace();}System.out.println("计数器最终结果:" + counter.getCount());}
}
-
使用Lock接口 代码例子:
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
class Counter {private int count = 0;private Lock lock = new ReentrantLock();public void increment() {lock.lock(); // 加锁try {count++;} finally {lock.unlock(); // 解锁}}public int getCount() {return count;}
}
// 线程控制逻辑与上一个例子类似,此处不再赘述
三、线程通信
线程通信主要涉及到wait()、notify()和notifyAll()这三个方法。 代码例子:
class ProducerConsumer {private int product = 0;private boolean isEmpty = true;public synchronized void produce() {while (!isEmpty) {try {wait(); // 等待消费者消费} catch (InterruptedException e) {e.printStackTrace();}}product++;System.out.println("生产者生产了产品:" + product);isEmpty = false;notifyAll(); // 通知消费者}public synchronized void consume() {while (isEmpty) {try {wait(); // 等待生产者生产} catch (InterruptedException e) {e.printStackTrace();}}System.out.println("消费者消费了产品:" + product);isEmpty = true;notifyAll(); // 通知生产者}
}
public class Main {public static void main(String[] args) {ProducerConsumer pc = new ProducerConsumer();Thread producer = new Thread(() -> {for (int i = 0; i < 10; i++) {pc.produce();}});Thread consumer = new Thread(() -> {for (int i = 0; i < 10; i++) {pc.consume();}});producer.start();consumer.start();}
}
四、线程调度
Java提供了线程调度器来控制线程的执行顺序。
-
设置线程优先级 代码例子:
Thread t1 = new Thread(() -> {// 线程执行体
});
t1.setPriority(Thread.MAX_PRIORITY); // 设置线程优先级为最高
Thread t2 = new Thread(() -> {// 线程执行体
});t2.setPriority(Thread.MIN_PRIORITY); // 设置线程优先级为最低
t1.start();
t2.start();
-
使用线程池 线程池可以有效地管理和控制线程的创建和销毁,提高系统性能。 代码例子:
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class Main {public static void main(String[] args) {// 创建固定大小的线程池ExecutorService executorService = Executors.newFixedThreadPool(5);// 提交任务到线程池for (int i = 0; i < 10; i++) {executorService.execute(() -> {// 线程执行体System.out.println("线程池中的线程正在执行:" + Thread.currentThread().getName());});}// 关闭线程池executorService.shutdown();}
}
五、线程中断
线程中断是一种协作机制,用于通知线程中断其正在执行的任务。 代码例子:
class MyRunnable implements Runnable {@Overridepublic void run() {while (!Thread.currentThread().isInterrupted()) {// 执行任务System.out.println("线程正在执行任务");try {Thread.sleep(1000); // 模拟耗时操作} catch (InterruptedException e) {// 捕获中断异常,并设置中断标志Thread.currentThread().interrupt();e.printStackTrace();}}System.out.println("线程被中断,退出任务");}
}
public class Main {public static void main(String[] args) throws InterruptedException {Thread thread = new Thread(new MyRunnable());thread.start();// 主线程休眠一段时间后中断子线程Thread.sleep(3000);thread.interrupt();}
}
六、线程局部变量
ThreadLocal类可以创建线程局部变量,确保每个线程都有自己独立的变量副本。
代码例子:
import java.util.concurrent.atomic.AtomicInteger;
public class Main {// 创建线程局部变量private static final ThreadLocal<Integer> threadLocalValue = new ThreadLocal<Integer>() {@Overrideprotected Integer initialValue() {return new AtomicInteger().incrementAndGet();}};public static void main(String[] args) {// 在不同线程中访问线程局部变量Thread t1 = new Thread(() -> {System.out.println("线程1的局部变量值:" + threadLocalValue.get());});Thread t2 = new Thread(() -> {System.out.println("线程2的局部变量值:" + threadLocalValue.get());});t1.start();t2.start();}
}
七、总结
通过这些机制,我们可以更好地管理和控制线程的执行,编写出高效、稳定的并发程序。