线程安全
发布日期:2021-06-27 12:56:02
浏览次数:27
分类:技术文章
本文共 4659 字,大约阅读时间需要 15 分钟。
多线程之间由于抢占式运行,存在线程不安全的问题。如:
public class Demo_safe { public static void main(String[] args) { //线程不安全 Runnable run = new Ticket(); new Thread(run).start(); new Thread(run).start(); new Thread(run).start(); } static class Ticket implements Runnable{ //票数 private int count = 10; @Override public void run() { while (count>0){ //卖票 System.out.println("准备卖票"); try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } count--; System.out.println("出票成功,余票:"+count); } } }}
输出:准备卖票准备卖票准备卖票出票成功,余票:8准备卖票出票成功,余票:9准备卖票出票成功,余票:7准备卖票出票成功,余票:4准备卖票出票成功,余票:5准备卖票出票成功,余票:6准备卖票出票成功,余票:1准备卖票出票成功,余票:2准备卖票出票成功,余票:3准备卖票出票成功,余票:-2出票成功,余票:-1出票成功,余票:0
出现了负数,明显不合理,存在不安全问题
实现线程安全有如下方法:
一、同步代码块
格式:synchronized(锁对象){}
注意: 一定要所有线程都看同一把锁才能保证排队,以保证线程安全。
import java.io.ObjectOutputStream;public class Demo_safe1 { public static void main(String[] args) { //线程不安全 Runnable run = new Ticket(); new Thread(run).start(); new Thread(run).start(); new Thread(run).start(); } static class Ticket implements Runnable { //票数 private int count = 10; private Object o = new Object(); @Override public void run() { while (true) { synchronized (o) { if (count > 0) { //卖票 System.out.println("准备卖票"); try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } count--; System.out.println(Thread.currentThread().getName() + "出票成功,余票:" + count); }else { break; } } } } }}
准备卖票Thread-0出票成功,余票:9准备卖票Thread-0出票成功,余票:8准备卖票Thread-0出票成功,余票:7准备卖票Thread-0出票成功,余票:6准备卖票Thread-0出票成功,余票:5准备卖票Thread-0出票成功,余票:4准备卖票Thread-2出票成功,余票:3准备卖票Thread-2出票成功,余票:2准备卖票Thread-2出票成功,余票:1准备卖票Thread-2出票成功,余票:0
二、同步方法
public class Demo_safe2 { public static void main(String[] args) { //线程不安全 Runnable run = new Ticket(); new Thread(run).start(); new Thread(run).start(); new Thread(run).start(); } static class Ticket implements Runnable { //票数 private int count = 10; @Override public void run() { while (true) { boolean flag = sale(); if (!flag){ break; } } } public synchronized boolean sale(){ if (count > 0) { //卖票 System.out.println("准备卖票"); try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } count--; System.out.println(Thread.currentThread().getName()+"出票成功,余票:" + count); return true; }else { return false; } } }}
以上同步代码块 与 同步方法 都属于隐式锁
三、显示锁Lock
其子类 ReentrantLockimport java.util.concurrent.locks.Lock;import java.util.concurrent.locks.ReentrantLock;public class Demo_safe3 { public static void main(String[] args) { //线程不安全 Runnable run = new Ticket(); new Thread(run).start(); new Thread(run).start(); new Thread(run).start(); } static class Ticket implements Runnable { //票数 private int count = 10; //显示锁 //private Lock l = new ReentrantLock(true); 当传入参数"true",则表示为公平锁 private Lock l = new ReentrantLock(); @Override public void run() { while (true) { l.lock(); if (count > 0) { //卖票 System.out.println("准备卖票"); try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } count--; System.out.println(Thread.currentThread().getName()+"出票成功,余票:" + count); }else { break; } l.unlock(); } } }}
转载地址:https://blog.csdn.net/weixin_43454088/article/details/117338555 如侵犯您的版权,请留言回复原文章的地址,我们会给您删除此文章,给您带来不便请您谅解!
发表评论
最新留言
关注你微信了!
[***.104.42.241]2024年03月18日 11时39分12秒
关于作者
喝酒易醉,品茶养心,人生如梦,品茶悟道,何以解忧?唯有杜康!
-- 愿君每日到此一游!
推荐文章
linux搭建java开发环境_Linux搭建Java开发环境
2019-04-21
java 内存管理 知乎_[知乎]Java 语言的 GC 为什么不实时释放内存?
2019-04-21
java optional_JAVA Optional总结
2019-04-21
java格式化时间博客园_Java 日期格式化工具类
2019-04-21
java创建一个图形类getv_java建立类和对象分糖果
2019-04-21
java 新增注解_java annotation(如何创建新的注解)小结
2019-04-21
mysql 函数定义常量_php如何定义一个自定义常量
2019-04-21
约瑟夫问题java 递归_从约瑟夫问题的递归实现的问题说起
2019-04-21
mysql 索引表的应用_MySQL查询优化之索引的应用详解
2019-04-21
Java中文jsp页面_java中文乱码解决之道(七)—–JSP页面编码过程
2019-04-21
neatdm路径_网易有爱插件设置教程-网易有爱插件游戏路径如何设置
2019-04-21
oracle迁移mysql验证_ORACLE 迁移MYSQL 随笔
2019-04-21
类型不匹配 java_java – 与泛型类型不匹配
2019-04-21
专科转行学java_大专女生想转行做IT,应该先学哪一块?
2019-04-21
php取汉字拼音首字母,php获取汉字拼音首字母的函数(真正可以使用的)
2019-04-21