Java之线程与并发编程!
开篇语
哈喽,各位小伙伴们,你们好呀,我是喵手。运营社区:C站/掘金/腾讯云/阿里云/华为云/51CTO;欢迎大家常来逛逛
今天我要给大家分享一些自己日常学习到的一些知识点,并以文字的形式跟大家一起交流,互相学习,一个人虽可以走的更快,但一群人可以走的更远。
我是一名后端开发爱好者,工作日常接触到最多的就是Java语言啦,所以我都尽量抽业余时间把自己所学到所会的,通过文章的形式进行输出,希望以这种方式帮助到更多的初学者或者想入门的小伙伴们,同时也能对自己的技术进行沉淀,加以复盘,查缺补漏。
小伙伴们在批阅的过程中,如果觉得文章不错,欢迎点赞、收藏、关注哦。三连即是对作者我写作道路上最好的鼓励与支持!
前言
线程与并发编程是现代程序设计中至关重要的概念,尤其是在多核处理器的环境下。通过合理的线程管理与同步机制,程序能够更高效地执行任务,充分利用硬件资源。本文将深入探讨线程的创建与生命周期、Runnable
与Thread
类、同步与锁机制、线程池以及高级并发工具如CountDownLatch
、CyclicBarrier
、Semaphore
、Future
等。
1. 线程的创建与生命周期
线程的生命周期
线程的生命周期可以分为以下几个阶段:
- 新建(New):线程被创建,但还没有开始执行。
- 就绪(Runnable):线程已经准备好并等待操作系统分配CPU时间片。
- 运行(Running):线程获取到CPU资源后开始执行任务。
- 阻塞(Blocked):线程因为某些原因被阻塞,等待某些资源或条件。
- 死亡(Terminated):线程执行完毕或者被强制终止。
线程的创建
线程的创建有两种主要方式:
- 通过继承
Thread
类 - 通过实现
Runnable
接口
示例:
-
通过继承
Thread
类:class MyThread extends Thread { public void run() { System.out.println("Thread is running"); } } public class Main { public static void main(String[] args) { MyThread thread = new MyThread(); thread.start(); // 启动线程 } }
-
通过实现
Runnable
接口:class MyRunnable implements Runnable { public void run() { System.out.println("Runnable is running"); } } public class Main { public static void main(String[] args) { MyRunnable myRunnable = new MyRunnable(); Thread thread = new Thread(myRunnable); thread.start(); // 启动线程 } }
2. Runnable
与Thread
类
Thread
类
Thread
类是Java中最常见的线程类,它提供了创建和控制线程的基本方法。Thread
类可以通过继承和重写其run()
方法来实现线程的逻辑。
Runnable
接口
Runnable
接口是另一种创建线程的方式,它定义了一个run()
方法。通过实现Runnable
接口,线程可以使用多个线程共享同一个Runnable
实例。
区别:
- 使用
Thread
类时,每个线程只能继承一个类,因此无法继承其他类。 - 使用
Runnable
接口时,类可以继承其他类,同时实现多个接口,具有更高的灵活性。
示例:
// 通过Thread创建线程
class MyThread extends Thread {
public void run() {
System.out.println("Thread is running");
}
}
// 通过Runnable接口创建线程
class MyRunnable implements Runnable {
public void run() {
System.out.println("Runnable is running");
}
}
public class Main {
public static void main(String[] args) {
MyThread thread1 = new MyThread();
thread1.start(); // 启动线程
MyRunnable myRunnable = new MyRunnable();
Thread thread2 = new Thread(myRunnable);
thread2.start(); // 启动线程
}
}
3. 同步与锁机制
同步(Synchronization)
在多线程环境下,多个线程可能会同时访问共享资源,导致数据不一致或程序出错。为了避免这种问题,Java提供了同步机制。
- synchronized关键字:通过在方法或代码块上加上
synchronized
关键字,确保同一时间只有一个线程能够访问该资源。
示例:
class Counter {
private int count = 0;
// 使用synchronized保证线程安全
synchronized void increment() {
count++;
}
synchronized void decrement() {
count--;
}
public int getCount() {
return count;
}
}
锁机制
Java中的锁机制提供了更高级的同步方式,例如:
- ReentrantLock:相比
synchronized
,ReentrantLock
提供了更细粒度的控制,支持可重入锁、定时锁等功能。 - 读写锁(ReadWriteLock):适用于读多写少的场景,允许多个线程同时读共享资源,但写操作是排他的。
示例:
import java.util.concurrent.locks.ReentrantLock;
class Counter {
private int count = 0;
private ReentrantLock lock = new ReentrantLock();
void increment() {
lock.lock(); // 获取锁
try {
count++;
} finally {
lock.unlock(); // 释放锁
}
}
void decrement() {
lock.lock();
try {
count--;
} finally {
lock.unlock();
}
}
public int getCount() {
return count;
}
}
4. 线程池(Executor、ExecutorService)
线程池的概念
线程池是一个可以重用的线程集合,能够有效管理线程的生命周期。它通过预先创建和管理线程来减少线程的创建和销毁开销。
Java提供了Executor
框架来管理线程池,主要包含以下几种类型:
- Executor:最基础的线程池接口,提供了执行任务的能力。
- ExecutorService:扩展了
Executor
,提供了关闭线程池、提交任务、获取任务执行结果等功能。 - ScheduledExecutorService:用于定时和周期性任务的执行。
示例:
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class Main {
public static void main(String[] args) {
ExecutorService executor = Executors.newFixedThreadPool(2); // 创建一个固定大小的线程池
executor.submit(() -> {
System.out.println("Task 1 is running");
});
executor.submit(() -> {
System.out.println("Task 2 is running");
});
executor.shutdown(); // 关闭线程池
}
}
5. 高级并发:CountDownLatch、CyclicBarrier、Semaphore、Future等
CountDownLatch
CountDownLatch
是一个同步工具类,它允许一个或多个线程等待直到其他线程完成某些操作后再继续。CountDownLatch
通过计数器来控制线程的等待,计数器初始值为一个正整数,每次调用countDown()
方法将计数器减一,当计数器为零时,等待的线程继续执行。
示例:
import java.util.concurrent.CountDownLatch;
public class Main {
public static void main(String[] args) throws InterruptedException {
CountDownLatch latch = new CountDownLatch(3);
// 启动三个线程
for (int i = 0; i < 3; i++) {
new Thread(() -> {
System.out.println("Task is completed");
latch.countDown(); // 每个任务完成时调用countDown
}).start();
}
latch.await(); // 等待所有任务完成
System.out.println("All tasks are completed");
}
}
CyclicBarrier
CyclicBarrier
用于让一组线程在某个点上等待,直到所有线程都到达了这个点。与CountDownLatch
不同,CyclicBarrier
是可重用的,即在屏障释放后可以重复使用。
示例:
import java.util.concurrent.CyclicBarrier;
public class Main {
public static void main(String[] args) throws InterruptedException {
CyclicBarrier barrier = new CyclicBarrier(3, () -> {
System.out.println("All threads have reached the barrier, continue execution.");
});
// 启动三个线程
for (int i = 0; i < 3; i++) {
new Thread(() -> {
System.out.println("Thread is waiting at the barrier");
try {
barrier.await();
} catch (Exception e) {
e.printStackTrace();
}
}).start();
}
}
}
Semaphore
Semaphore
是一个计数信号量,允许控制同时访问某个资源的线程数量。Semaphore
常用于限制并发访问某些资源的线程数。
示例:
import java.util.concurrent.Semaphore;
public class Main {
public static void main(String[] args) throws InterruptedException {
Semaphore semaphore = new Semaphore(2); // 限制同时只有两个线程访问
for (int i = 0; i < 5; i++) {
new Thread(() -> {
try {
semaphore.acquire(); // 获取信号量
System.out.println(Thread.currentThread().getName() + " is working");
Thread.sleep(1000); // 模拟工作
semaphore.release(); // 释放信号量
} catch (InterruptedException e) {
e.printStackTrace();
}
}).start();
}
}
}
Future
Future
是一个接口,它表示异步计算的结果。通过Future
,可以在计算完成后获取返回结果、取消任务或者检测任务是否完成。
示例:
import java.util.concurrent.*;
public class Main {
public static void main(String[] args) throws ExecutionException, InterruptedException {
ExecutorService executor = Executors.newSingleThreadExecutor();
Future<Integer> future = executor.submit(() -> {
return 42; // 任务返回结果
});
Integer result = future.get(); // 获取任务结果
System.out.println("Result: " + result);
executor.shutdown();
}
}
总结
线程与并发编程是提高程序执行效率的关键技术。通过理解和应用线程的创建与生命周期、同步与锁机制、线程池的使用,以及掌握高级并发工具如CountDownLatch
、CyclicBarrier
、Semaphore
和Future
,可以有效地提升程序的性能、可扩展性与可维护性。在多线程编程中,合理的同步和资源管理至关重要,它们决定了程序的正确性和效率。
… …
文末
好啦,以上就是我这期的全部内容,如果有任何疑问,欢迎下方留言哦,咱们下期见。
… …
学习不分先后,知识不分多少;事无巨细,当以虚心求教;三人行,必有我师焉!!!
wished for you successed !!!
⭐️若喜欢我,就请关注我叭。
⭐️若对您有用,就请点赞叭。
⭐️若有疑问,就请评论留言告诉我叭。
版权声明:本文由作者原创,转载请注明出处,谢谢支持!
- 点赞
- 收藏
- 关注作者
评论(0)