
java解决线程不安全问题
发布日期:2021-05-18 05:58:53
浏览次数:12
分类:精选文章
本文共 2834 字,大约阅读时间需要 9 分钟。
解决线程不安全问题的两种方法
方法一:使用 synchronized 关键字
在 Java 中,synchronized
是一个非常有用的关键字,用于确保线程的安全。它可以保护共享资源免受多线程访问带来的问题。如果多个线程试图同时访问同一个对象的非静态成员变量或 выз同一方法,synchronized
会自动同步这些线程,确保一个线程在运行时其他线程必须等待,直到该线程完成。
这种方法通常用于线程安全问题的简单情况。通过将关键方法标记为 synchronized
,可以保证其他线程在访问时不会产生冲突。
方法二:使用 ReentrantLock 锁
ReentrantLock 是一种更灵活的线程安全工具,提供了更精细的控制。与 synchronized
不同的是,ReentrantLock 不会阻止线程在拥有锁的时候再次请求同一锁,这使得它特别适用于像数据库事务这样的场景。
ReentrantLock 由两种主要方法组成:lock()
和 unlock()
。使用 lock()
时,其他线程必须等待才能进入 synchronized 块;当执行完成后,使用 unlock()
将锁释放,允许其他线程继续执行。
这种方法与 synchronized
类似,但提供了更细粒度的锁控制,特别适用于复杂的线程同步需求。
代码示例
统计票号问题
方法一:
import java.util.concurrent.locks.ReentrantLock;public class WindowsTest1 { private static int count = 100; private static ReentrantLock rl = new ReentrantLock(true); // 使用fair Starlock public static void main(String[] args) { Window1 w = new Window1(); Thread t1 = new Thread(w); Thread t2 = new Thread(w); Thread t3 = new Thread(w); t1.setName("窗口1"); t2.setName("窗口2"); t3.setName("窗口3"); t1.start(); t2.start(); t3.start(); }}class Window1 implements Runnable { private static synchronized void show() { if (count-- > 0) { try { Thread.sleep(100); } catch (InterruptedException e) { System.out.println(e.getMessage()); } System.out.println(Thread.currentThread().getName() + "购票成功,票号为:" + (count + 1)); } }}
方法二:
import java.util.concurrent.locks.ReentrantLock;public class WindowsTest1 { private static int count = 100; private static ReentrantLock rl = new ReentrantLock(true); public static void main(String[] args) { Window1 w = new Window1(); Thread t1 = new Thread(w); Thread t2 = new Thread(w); Thread t3 = new Thread(w); t1.setName("窗口1"); t2.setName("窗口2"); t3.setName("窗口3"); t1.start(); t2.start(); t3.start(); }}class Window1 implements Runnable { private static ReentrantLock rl = new ReentrantLock(true); public void run() { while (count >= 0) { try { rl.lock(); show(); } catch (Exception e) { e.printStackTrace(); } finally { rl.unlock(); } } } private static void show() { if (count-- > 0) { try { Thread.sleep(100); } catch (InterruptedException e) { System.out.println(e.getMessage()); } System.out.println(Thread.currentThread().getName() + "购票成功,票号为:" + (count + 1)); } }}
结论
两种方法都能有效地解决线程不安全问题,但如果需要更细粒度的锁控制,ReentrantLock 和锁机制可能更适合复杂场景。选择哪种方法取决于具体需求和线程调用的复杂程度。在实践中,两种方法都是常用的线程安全工具。
发表评论
最新留言
表示我来过!
[***.240.166.169]2025年05月06日 16时59分08秒
关于作者

喝酒易醉,品茶养心,人生如梦,品茶悟道,何以解忧?唯有杜康!
-- 愿君每日到此一游!
推荐文章
什么是证券型代币?
2019-03-14
Android中获取并设置屏幕亮度
2019-03-14
Windows抓包工具-Fiddler
2019-03-14
Swift中使用DispatchGroup分组管理异步任务
2019-03-14
21-JS中常见的函数
2019-03-14
Android多线程与双缓冲
2019-03-14
MVVM_Template
2019-03-14
Bugku CTF web29(Web)
2019-03-14
网络+图片加载框架(英文版)
2019-03-14
扣非净利润连续三年亏损,四维图新如何熬过“转型阵痛期”?
2019-03-14
Python imageio方法示例
2019-03-14
Possible missing firmware
2019-03-14
算法的学习方式
2019-03-14
JAVA BigInteger和BigDecimal类常用方式
2019-03-14
深度学习框架 各种模型下载集合 -- models list
2019-03-14
six.move 的作用
2019-03-14
机器学习全教程
2019-03-14
idea在连接mysql数据库时区错误
2019-03-14
2021-05-14
2019-03-14