文章目录
1. 引言
在现代软件开发中,多线程编程是必不可少的一部分。Java提供了丰富的并发编程支持,使得开发者能够编写高性能、高可靠性的应用程序。本文将详细介绍Java中的并发编程基础,并通过具体的代码示例展示如何使用Java的并发工具类来实现高效的并发编程。
2. Java并发编程基础
Java并发编程主要涉及以下几个核心概念:
线程:线程是操作系统能够进行运算调度的最小单位,它是进程的一个实体,是CPU调度和分派的基本单位。
线程安全:确保多个线程同时访问共享资源时不会产生数据不一致的问题。
同步机制:通过锁或其他机制来保证线程之间的正确协作。
并发工具类:Java提供了许多并发工具类,如ExecutorService、Future、CountDownLatch等,以简化并发编程。
3. 线程创建与管理
在Java中,可以通过多种方式创建线程:
3.1 继承Thread类
/**
* MyThread
* @author senfel
* @version 1.0
* @date 2024/9/25 17:18
*/
public class MyThread extends Thread {
@Override
public void run() {
System.out.println("Running in thread: " + Thread.currentThread().getName());
}
public static void main(String[] args) {
MyThread thread = new MyThread();
thread.start();
}
}
3.2 实现Runnable接口
/**
* MyRunnable
* @author senfel
* @version 1.0
* @date 2024/9/25 17:19
*/
public class MyRunnable implements Runnable {
@Override
public void run() {
System.out.println("Running in thread: " + Thread.currentThread().getName());
}
public static void main(String[] args) {
Thread thread = new Thread(new MyRunnable());
thread.start();
}
}
3.3 使用Callable与Future
/**
* MyCallable
* @author senfel
* @version 1.0
* @date 2024/9/25 17:21
*/
public class MyCallable implements Callable<Integer> {
@Override
public Integer call() throws Exception {
int sum = 0;
for (int i = 0; i < 100000; i++) {
sum += i;
}
return sum;
}
public static void main(String[] args) throws ExecutionException, InterruptedException {
ExecutorService executor = Executors.newSingleThreadExecutor();
Future<Integer> future = executor.submit(new MyCallable());
int result = future.get();
System.out.println("Result: " + result);
executor.shutdown();
}
}
4. 线程同步
在多线程环境中,线程同步是非常重要的。Java提供了多种同步机制:
4.1 synchronized关键字
/**
* Counter
* @author senfel
* @version 1.0
* @date 2024/9/25 17:23
*/
public class Counter {
private int count = 0;
public synchronized void increment() {
count++;
}
public synchronized int getCount() {
return count;
}
public static void main(String[] args) throws InterruptedException {
Counter counter = new Counter();
Thread t1 = new Thread(() -> {
for (int i = 0; i < 10000; i++) {
counter.increment();
}
});
Thread t2 = new Thread(() -> {
for (int i = 0; i < 10000; i++) {
counter.increment();
}
});
t1.start();
t2.start();
t1.join();
t2.join();
System.out.println("Final count: " + counter.getCount());
}
}
4.2 ReentrantLock
/**
* CounterWithLock
* @author senfel
* @version 1.0
* @date 2024/9/25 17:23
*/
public class CounterWithLock {
private int count = 0;
private final Lock lock = new ReentrantLock();
public void increment() {
lock.lock();
try {
count++;
} finally {
lock.unlock();
}
}
public int getCount() {
return count;
}
public static void main(String[] args) throws InterruptedException {
CounterWithLock counter = new CounterWithLock();
Thread t1 = new Thread(() -> {
for (int i = 0; i < 10000; i++) {
counter.increment();
}
});
Thread t2 = new Thread(() -> {
for (int i = 0; i < 10000; i++) {
counter.increment();
}
});
t1.start();
t2.start();
t1.join();
t2.join();
System.out.println("Final count: " + counter.getCount());
}
}
5. 并发工具类
Java提供了许多并发工具类,以简化并发编程。
5.1 ExecutorService
线程池的一个接口类ExecutorService,下面我们来了解下java中Executors的线程池。
Java通过Executors提供四种线程池,分别为:
newCachedThreadPool创建一个可缓存线程池,如果线程池长度超过处理需要,可灵活回收空闲线程,若无可回收,则新建线程。
newFixedThreadPool 创建一个定长线程池,可控制线程最大并发数,超出的线程会在队列中等待。
newScheduledThreadPool 创建一个定长线程池,支持定时及周期性任务执行。
newSingleThreadExecutor 创建一个单线程化的线程池,它只会用唯一的工作线程来执行任务,保证所有任务按照指定顺序(FIFO, LIFO, 优先级)执行。
/**
* ExecutorServiceExample
* @author senfel
* @version 1.0
* @date 2024/9/25 17:26
*/
public class ExecutorServiceExample {
public static void main(String[] args) {
ExecutorService executor = Executors.newFixedThreadPool(5);
for (int i = 0; i < 10; i++) {
int taskId = i;
executor.submit(() -> {
System.out.println("Executing task " + taskId + " in thread: " + Thread.currentThread().getName());
});
}
executor.shutdown();
}
}
5.2 CountDownLatch
让某一个线程等待多个线程的操作完成之后再执行。它可以使一个或多个线程等待一组事件的发生,而其他的线程则可以触发这组事件。
/**
* CountDownLatchExample
* @author senfel
* @version 1.0
* @date 2024/9/25 17:26
*/
public class CountDownLatchExample {
public static void main(String[] args) throws InterruptedException {
CountDownLatch latch = new CountDownLatch(3);
Thread t1 = new Thread(() -> {
System.out.println("Thread 1 started");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("Thread 1 finished");
latch.countDown();
});
Thread t2 = new Thread(() -> {
System.out.println("Thread 2 started");
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("Thread 2 finished");
latch.countDown();
});
Thread t3 = new Thread(() -> {
System.out.println("Thread 3 started");
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("Thread 3 finished");
latch.countDown();
});
t1.start();
t2.start();
t3.start();
System.out.println("Waiting for all threads to finish...");
latch.await();
System.out.println("All threads have finished.");
}
}
6. 总结
通过本文的介绍,我们了解了Java并发编程的基础知识,并通过具体的代码示例展示了如何使用Java的并发工具类来实现高效的并发编程。这些技术不仅使代码更加简洁易读,还能提高程序的执行效率。希望这篇博客能为你理解和使用Java中的并发编程提供一些帮助。