4000-520-616
欢迎来到免疫在线!(蚂蚁淘生物旗下平台)  请登录 |  免费注册 |  询价篮
主营:原厂直采,平行进口,授权代理(蚂蚁淘为您服务)
咨询热线电话
4000-520-616
当前位置: 首页 > 新闻动态 >
热卖商品
新闻详情
packagecom.sxt.syn;/***线程安全:在并发时保证数据的正确性...
来自 : CSDN技术社区 发布时间:2021-03-24

\"在这里插入图片描述\"

synchronized方法

package com.sxt.syn;/** * 线程安全: 在并发时保证数据的正确性、效率尽可能高 * synchronized * 1、同步方法 * 2、同步块 * author * */public class SynTest01 { public static void main(String[] args) { //一份资源 SafeWeb12306 web new SafeWeb12306(); //多个代理 new Thread(web, 码畜 ).start(); new Thread(web, 码农 ).start(); new Thread(web, 码蟥 ).start();; }}class SafeWeb12306 implements Runnable{ //票数 private int ticketNums private boolean flag true; Override public void run() { while(flag) { try { Thread.sleep(100); } catch (InterruptedException e) { e.printStackTrace(); } test(); } } //线程安全 同步 public synchronized void test() { if(ticketNums 0) { flag false; return ; } //模拟延时 try { Thread.sleep(200); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(Thread.currentThread().getName() -- ticketNums--); }}

synchronized是锁对象的资源。
我们数据都是在方法里面操作的 我们通过方法就可以去控制这个数据了。通过块也能去保证数据的安全。
锁了(方法)资源 这个资源是对象的资源 那此时这个对象是this 方法里面的资源是不是都是和这个对象相关的资源 如果不是就琐失败了。

package com.sxt.syn;/** * 线程安全: 在并发时保证数据的正确性、效率尽可能高 * synchronized * 1、同步方法 * 2、同步块 * author * */public class SynTest02 { public static void main(String[] args) { //账户 Account account new Account(100, 结婚礼金 SafeDrawing you new SafeDrawing(account,80, 可悲的你 SafeDrawing wife new SafeDrawing(account,90, happy的她 you.start(); wife.start(); }} class Account{ int money; //金额 String name; //名称 public Account(int money, String name) { this.money money; this.name name; } //模拟取款class SafeDrawing extends Thread{ Account account ; //取钱的账户 int drawingMoney ;//取的钱数 int packetTotal ; //口袋的总数 public SafeDrawing(Account account, int drawingMoney,String name) { super(name); this.account account; this.drawingMoney drawingMoney; } Override public void run() { test(); } //目标不对锁定失败 这里不是锁this 应该锁定 account public synchronized void test() { if(account.money -drawingMoney 0) { return; } try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } account.money - drawingMoney; packetTotal drawingMoney; System.out.println(this.getName() -- 账户余额为: account.money); System.out.println(this.getName() -- 口袋的钱为: packetTotal); }}

一定要理解到位 什么时候锁上了 什么时候没锁上 为什么要锁它 线程不安全是哪里造成的 原因是什么。一定要学会分析 比如刚刚的负数、相同的情况是怎么产生的啊 加了synchronized为什么没锁上 这些都是线程的难点。

synchronized块
\"在这里插入图片描述\"

刚刚我们发现使用同步方法锁的这个资源的对象不对 因为默认情况下这个成员方法是this 因此 我要锁一个具体的对象该怎么办呢 借助synchronized同步块
synchronized同步块在小括号里面填入的是一个具体的对象 比如丢入Account对象、this或者丢入模子的信息 小括号里才是我们需要锁定的对象。然后花括号里面写入代码 我们将花括号的代码一般来说就称为块 加入了synchronized就称为“同步块”。
Java里面的块有四种
1、方法里面写一个块 我们称为局部块 普通块 用来解决变量的作用域 快速释放内存
2、如果是在类中方法外写一个块 这个块我们称为构造块 作用和构造器一样 用来初始“对象”信息的。
3、如果在构造块上加一个static 我们称为静态块 静态块和构造块的区别是 静态块加载一次是用于初始化类的 先于构造块执行。
4、最后一个是同步块 也是在方法里面 用于解决线程安全的问题。

同步监视器的执行过程
\"在这里插入图片描述\"

package com.sxt.syn;/** * 线程安全: 在并发时保证数据的正确性、效率尽可能高 * synchronized * 1、同步方法 * 2、同步块 ,目标更明确 * author * */public class SynBlockTest01 { public static void main(String[] args) { //账户 Account account new Account(1000, 结婚礼金 SynDrawing you new SynDrawing(account,80, 可悲的你 SynDrawing wife new SynDrawing(account,90, happy的她 you.start(); wife.start(); }} //模拟取款 线程安全class SynDrawing extends Thread{ Account account ; //取钱的账户 int drawingMoney ;//取的钱数 int packetTotal ; //口袋的总数 public SynDrawing(Account account, int drawingMoney,String name) { super(name); this.account account; this.drawingMoney drawingMoney; } Override public void run() { test() ; } //目标锁定account public void test() { //提高性能 if(account.money 0) { return ; } //同步块 synchronized(account) { if(account.money -drawingMoney 0) { return; } try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } account.money - drawingMoney; packetTotal drawingMoney; System.out.println(this.getName() -- 账户余额为: account.money); System.out.println(this.getName() -- 口袋的钱为: packetTotal); } }}package com.sxt.syn;import java.util.ArrayList;import java.util.List;/** * 线程安全 操作容器 * * author * */public class SynBlockTest02 { public static void main(String[] args) throws InterruptedException { List String list new ArrayList String for(int i i 10000;i ) { new Thread(()- { //同步块 synchronized(list) { list.add(Thread.currentThread().getName()); } }) .start(); } Thread.sleep(10000); System.out.println(list.size()); }}

上面的案例除了main方法没有其他方法 我们锁main方法没有用 方法中使用的是lambda表达式 所以没有方法我们锁谁呢 我们锁不了main方法 只能锁List。synchronized(list){list.add(Thread.currentThread().getName());}。在添加的时候保证是拿到锁的。
在上面这个案例中如果没有加最后的Thread.sleep(),最后执行的结果也是不正确的 这是因为main方法中有“多个线程”和“主线程” “多个线程”没有执行完 main方法就先执行完了– System.out.println(list.size());

\"\" \"\" \"\" 点赞 \"\" \"\" 评论

本文链接: http://synblock.immuno-online.com/view-711948.html

发布于 : 2021-03-24 阅读(0)
公司介绍
品牌分类
联络我们
服务热线:4000-520-616
(限工作日9:00-18:00)
QQ :1570468124
手机:18915418616
官网:http://