
一文搞懂Java多线程基础(锁机制、线程通信、线程池)
发布日期:2021-05-08 16:15:58
浏览次数:17
分类:精选文章
本文共 3951 字,大约阅读时间需要 13 分钟。
Java多线程入门指南
1. 理解进程与线程
在计算机操作系统中,进程和线程是资源管理的核心概念。进程被认为是资源分配和调度的最小单位,而线程则是程序执行的最小单位。每个进程可以包含一个或多个线程,线程之间共享同一进程的内存空间。
进程特征
- 动态性:进程是临时的,随着任务需求动态创建和消亡。
- 并发性:进程可以与其他进程并行执行。
- 独立性:进程是资源分配的基本单位。
- 结构性:由程序、数据和控制块组成。
线程特性
- 轻量级:线程上下文切换比进程快,适合处理I/O密集型任务。
- 共享内存:同一进程内的线程共享程序内存空间。
- 并发执行:线程之间可以并发执行,提升系统效率。
2. Java中线程的创建方式
在Java中,创建线程主要通过以下方式:
1. 继承Thread类
- 步骤:
- 创建自定义Thread子类,重写
run()
方法。 - 创建线程实例。
- 调用
start()
方法启动线程。
示例代码:
public class MyThread extends Thread { @Override public void run() { // 线程执行逻辑 }}MyThread mt = new MyThread();mt.start();
2. 实现Runnable接口
- 步骤:
- 创建Runnable接口实现类,重写
run()
方法。 - 创建Thread对象,将Runnable实例作为参数传递。
- 调用
start()
方法启动线程。
示例代码:
public class MyThread implements Runnable { @Override public void run() { // 线程执行逻辑 }}MyThread mt = new MyThread();new Thread(mt).start();
3. 匿名内部类
- 方式:
- 在方法内定义匿名内部类,继承Thread或实现Runnable。
- 重写
run()
方法。 - 创建Thread对象并启动。
示例代码:
public static void main(String[] args) { new Thread() { @Override public void run() { // 线程执行逻辑 } }.start();}
4. Runnable匿名类
- 方式:
- 创建Runnable匿名类,重写
run()
方法。 - 创建Thread对象并启动。
示例代码:
public static void main(String[] args) { Runnable r = new Runnable() { @Override public void run() { // 线程执行逻辑 } }; new Thread(r).start();}
3. 线程安全问题
多线程环境下,共享资源可能导致并发问题。解决方法是使用同步机制。
1. synchronized锁
- 作用:防止多个线程同时访问共享资源。
- 使用方式:修饰方法或代码块,确保同步访问。
示例代码:
synchronized (this) { // 共享资源访问逻辑}
2. ReentrantLock锁
- 特点:支持重入锁,手动加锁和解锁。
- 使用方式:调用
lock()
和unlock()
方法,确保锁的使用和释放。
示例代码:
ReentrantLock lock = new ReentrantLock();lock.lock();try { // 共享资源访问逻辑} finally { lock.unlock();}
3. lock和ReentrantLock对比
- synchronized:自动加锁和解锁,适合简单场景。
- ReentrantLock:手动控制锁,适合复杂需求,支持公平锁机制。
4. 线程通信
线程通信是多线程程序中常见的操作,常用wait()
、notify()
和notifyAll()
方法。
1. wait和notify
- 作用:wait方法让线程等待特定对象的通知,notify方法唤醒正在等待的线程。
示例代码:
public class MyThread extends Thread { public static void main(String[] args) { MyThread t1 = new MyThread(); t1.start(); try { t1.join(); } catch (InterruptedException e) { e.printStackTrace(); } } @Override public void run() { try { Thread.sleep(1000); System.out.println("线程1执行"); notify(); } catch (InterruptedException e) { e.printStackTrace(); } }}
2. notifyAll
- 作用:唤醒等待队列中所有线程。
示例代码:
public class MyThread extends Thread { public static void main(String[] args) { MyThread t1 = new MyThread(); MyThread t2 = new MyThread(); t1.start(); t2.start(); try { Thread.sleep(1000); t1.notifyAll(); } catch (InterruptedException e) { e.printStackTrace(); } } @Override public void run() { try { Thread.sleep(1000); System.out.println("线程" + getId() + "执行"); } catch (InterruptedException e) { e.printStackTrace(); } }}
5. 线程池
线程池是什么?
线程池是一个容纳多个线程的容器,线程可以反复使用,避免频繁创建线程。
线程池的好处
- 降低资源消耗:减少线程创建和销毁次数。
- 提高响应速度:任务立即执行。
- 提高可管理性:根据需求调整线程数。
线程池的实现
import java.util.concurrent.ThreadPoolExecutor;import java.util.concurrent.TimeUnit;public class Main { public static void main(String[] args) { ThreadPoolExecutor executor = new ThreadPoolExecutor(2, 5, 10, TimeUnit.SECONDS); executor.execute(new Runnable() { @Override public void run() { try { Thread.sleep(1000); System.out.println("新线程执行"); } catch (InterruptedException e) { e.printStackTrace(); } } }); try { TimeUnit.SECONDS.sleep(2); executor.shutdown(); } catch (InterruptedException e) { e.printStackTrace(); } }}
6. 总结
通过以上内容,我们全面了解了Java中的多线程编程,包括线程的创建、线程安全问题、线程通信以及线程池的使用。掌握这些知识点是写高效、可靠的多线程程序的基础。
发表评论
最新留言
留言是一种美德,欢迎回访!
[***.207.175.100]2025年04月16日 00时56分43秒
关于作者

喝酒易醉,品茶养心,人生如梦,品茶悟道,何以解忧?唯有杜康!
-- 愿君每日到此一游!
推荐文章
LeetCode--020--括号匹配
2025-04-05
leetcode-28-Implement strStr()
2025-04-05
Leetcode-966 Vowel Spellchecker(元音拼写检查器)
2025-04-05
Leetcode-991 Broken Calculator(坏了的计算器)
2025-04-05
LeetCode-Binary Tree Maximum Path Sum
2025-04-05
LeetCode.两数之和&三数之和&最接近的三数之和&四数之和
2025-04-05
LeetCode110.平衡二叉树
2025-04-05
LeetCode111.二叉树最小深度
2025-04-05
LeetCode114.二叉树展开为链表[后序遍历典例]
2025-04-05
LeetCode136.只出现一次的数字[异或运算典例]
2025-04-05
LeetCode13:罗马数字转整数
2025-04-05
leetcode190-颠倒二进制位
2025-04-05
leetcode191-打家劫舍
2025-04-05
leetcode23-合并K个升序链表
2025-04-05
leetcode231 判断一个给定的整数是否是2的n次幂
2025-04-05
leetcode238-除自身以外数组的乘积
2025-04-05
LeetCode240:Search a 2D Matrix II
2025-04-05
LeetCode268.缺失数字
2025-04-05
LeetCode331.验证二叉树的前序序列化
2025-04-05