在Java中,并发编程是处理多个任务同时执行的一种重要方式。Java并发工具包(java.util.concurrent,简称JUC)在Java 5版本中被引入,提供了大量实用的工具类,用于多线程编程中的线程同步、协调和并发控制。下面将详细探讨Java并发编程中的多线程、锁以及并发工具类的使用。
1. 多线程的实现方式
在Java中,多线程的实现主要有以下几种方式:
-
继承Thread类:
通过继承Thread类并重写其run方法来实现多线程。这种方式简单直接,但Java不支持多重继承,如果类已经继承了其他类,则无法再继承Thread类。java复制代码
public class CreateThreadDemo1 extends Thread {
public void run() {
System.out.println("当前运行的线程名为: " + Thread.currentThread().getName());
}
public static void main(String[] args) throws Exception {
new CreateThreadDemo1("MyThread1").start();
new CreateThreadDemo1("MyThread2").start();
}
}
-
实现Runnable接口:
实现Runnable接口并重写其run方法,然后通过Thread类的构造器创建Thread实例,并调用其start方法。这种方式更加灵活,因为Java类可以实现多个接口。java复制代码
public class CreateThreadDemo2 implements Runnable {
public void run() {
System.out.println("当前运行的线程名为: " + Thread.currentThread().getName());
}
public static void main(String[] args) throws Exception {
Thread thread1 = new Thread(new CreateThreadDemo2(), "MyThread1");
Thread thread2 = new Thread(new CreateThreadDemo2(), "MyThread2");
thread1.start();
thread2.start();
}
}
-
实现Callable接口:
Callable接口类似于Runnable接口,但Callable的call方法可以返回结果。通过FutureTask和ExecutorService可以实现有返回值的线程。java复制代码
public class MyCallable implements Callable<Integer> {
public Integer call() throws Exception {
return 6 + 9;
}
public static void main(String[] args) throws Exception {
FutureTask<Integer> futureTask = new FutureTask<>(new MyCallable());
Thread thread = new Thread(futureTask);
thread.start();
System.out.println("返回值为: " + futureTask.get());
}
}
2. 锁
在Java中,锁是控制多个线程访问共享资源的关键机制。Java提供了多种锁的实现,如ReentrantLock、ReadWriteLock等。
-
ReentrantLock:
提供了比synchronized更灵活的锁定机制,支持中断等待锁的线程、尝试非阻塞地获取锁以及定时锁等。java复制代码
Lock lock = new ReentrantLock();
lock.lock();
try {
// 更新对象状态
} finally {
lock.unlock();
}
-
ReadWriteLock:
允许多个读线程同时访问共享资源,但每次只允许一个写线程。适用于读多写少的场景。java复制代码
ReadWriteLock rwLock = new ReentrantReadWriteLock();
Lock readLock = rwLock.readLock();
Lock writeLock = rwLock.writeLock();
readLock.lock();
try {
// 读取操作
} finally {
readLock.unlock();
}
writeLock.lock();
try {
// 写入操作
} finally {
writeLock.unlock();
}
3. 并发工具类
JUC包中提供了许多并发工具类,如CountDownLatch、CyclicBarrier和Semaphore等,用于解决复杂的并发问题。
-
CountDownLatch:
用于一个或多个线程等待其他线程完成操作。在创建CountDownLatch对象时,需要指定一个计数值,每当一个线程完成任务时,就调用countDown()方法将计数器减一,当计数器变为零时,等待的线程会继续执行。java复制代码
CountDownLatch latch = new CountDownLatch(3);
for (int i = 0; i < 3; i++) {
new Thread(() -> {
// 模拟任务
latch.countDown();
}).start();
}
latch.await(); //