上锁,根据操作系统所说的原则,对共享变量上锁,对临界区上锁。谁访问临界资源?就给谁上锁

同步监视器,它上锁的对象。

1.用关键字给方法上锁

2.用synchronized代码块上锁

默认上锁对象:this,指向自身。就是调用这个方法的对象,给他上锁。

安全的买票(给方法上锁)

public class SynchronizeTest {
//线程不安全
public static void main(String[] args) {
BuyTicker buyTicker = new BuyTicker();
new Thread(buyTicker,"lhh").start();
new Thread(buyTicker,"jhj").start();
new Thread(buyTicker,"黄牛").start();
}
}
class BuyTicker implements Runnable{
private int ticketNum = 10;
boolean flag = true;
@Override
public void run() {
while(flag){//外部停止方式
try {
buy();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}//对买票上锁,锁的this,this是指当前的对象。
public synchronized void buy() throws InterruptedException {//直接给方法上锁
//判断是否有票
if(ticketNum<=0){
System.out.println(Thread.currentThread().getName()+"票卖完了");
flag = false;
return;
}
Thread.sleep(100);
System.out.println(Thread.currentThread().getName()+"拿到"+ticketNum--);
}
}

安全的银行(给临界区上锁,)

如果给一个类的方法上锁了,实际上是给this也就是调用方法的这个对象上锁,比如你要是给run()上锁,就相当于你去取钱把银行锁了。但是取钱的人都还在银行里面。所以是要对账户上锁,因为我们逍遥操控的变量就是账户。

public class UnsafeBake {
public static void main(String[] args) {
Account account = new Account("结婚基金",1000);
Draw you = new Draw(account,50,"你");
Draw girlFriend = new Draw(account,100,"女朋友");
you.start();
girlFriend.start();
}
}
class Account{
String name;
int money;
public Account(String name, int money) {
this.name = name;
this.money = money;
}
}
class Draw extends Thread{
Account account;
int drawMoney;
int noMoney;
public Draw(Account account, int drawMoney, String name) {
super(name);
this.account = account;
this.drawMoney = drawMoney;
}
@Override
public void run() {
synchronized (account){
if(account.money-drawMoney<0){
System.out.println("余额不足");
return;
}
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
account.money = account.money - drawMoney;
noMoney = noMoney +drawMoney;
System.out.println(account.name+"余额为:"+account.money);
System.out.println(this.getName()+"手里的钱"+noMoney);//继承THread可以直接写this
}
}
}

安全的列表

public class UnsafeList {
public static void main(String[] args) {
List<String> list = new ArrayList<String>();
for (int i = 0; i < 100; i++) {
new Thread(()->{//lambda表达式
synchronized (list){//上锁临界资源list,下面是临界区操作临界资源的代码
list.add(Thread.currentThread().getName());
}
}).start();
}
try {
Thread.sleep(1000);//如果不让他睡,程序结束的时候线程也结束了一半了,列表元素就不够100
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(list.size());
}
}

syncronized如何上锁的更多相关文章

  1. ucos_ii 上锁函数OSSchedLock()函数透析

    因为任务调度时一般都是通过OSTIMEDLY()来实现.在这个函数中会对当前的任务执行挂起.同时查看任务调度表中是否有优先级合适的就绪任务.如果当前任务运行时调用OSSchedLock()给调度器上锁 ...

  2. QReadWriteLock上锁容忍的等待时间是多久?

    非递归上锁情况下,同一个锁,已经被锁过一次,那么另外一个线程尝试上锁,会被挡在外面,但是会被挡多久呢?挡一分钟会被崩溃,还十分钟,还是永久等待而不崩溃(希望如此)?还是会立刻崩溃?因为不可以重复上锁. ...

  3. RocksDB上锁机制

    RocksDB作为一个开源的存储引擎支持事务的ACID特性,而要支持ACID中的I(Isolation),并发控制这块是少不了的,本文主要讨论RocksDB的锁机制实现,细节会涉及到源码分析,希望通过 ...

  4. UNIX环境高级编程——记录上锁(fcntl函数)以及死锁检测

    一.记录锁 record locking 功能:当一个进程正在读或修改文件的某个部分时,它可以阻止其它进程修改同一文件区. 字节范围锁 byte-range locking 二.历史 flock函数, ...

  5. 在右键菜单中加入BitLocker重新上锁功能

    当使用BitLocker给磁盘上锁后,可以通过命令:manage-bde -lock d: -forcedismount 将已经解锁的磁盘重新上锁,如果觉得每次都通过命令行写命令很麻烦,那可以通过修改 ...

  6. Python用上锁和解锁 lock lock.acquire lock.release 模拟抢火车票

    Python用上锁和解锁  lock lock.acquire lock.release 模拟抢火车票 import jsonimport timefrom multiprocessing impor ...

  7. Lock为线程上锁,防止数据混乱

    用法: 先实例化  lock = threading.Lock() 1. lock.acquire() 上锁 需上锁代码 lock.release() 解锁 2. with lock: 上下两种方式都 ...

  8. 批处理系列(18) - 基于BitLocker的开锁上锁

    首先要配置好BitLocker. 上锁 lock.bat @echo off rem 上锁前要结束一些程序,浏览器要注意:有恢复上次关闭项功能,按需设置取消该操作 taskkill /f /t /im ...

  9. Android 手动按power键上锁,没有锁屏提示音,无法恢复【单机必现】

    測试步骤 [測试版本号]T0606 [模块版本号] NAVI锁屏:5.0.0.ck [測试步骤] 1.手动按power键上锁, [測试结果] 没有锁屏提示音,无法恢复[单机必现] [预期结果] 有提示 ...

随机推荐

  1. Natas11 Writeup(常见编码、异或逆推、修改cookie)

    Natas11: 页面提示cookie被异或加密保护,查看源码,发现了一个预定义参数和三个函数. //预定义参数,猜测将showpassword设置为yes即可得到密码. $defaultdata = ...

  2. 关于CORS(跨域资源共享)的几个http请求头小实验

    对几种与跨域相关的请求头做一个总结 关于跨域可以看:9 种常见的前端跨域解决方案(详解) 看完后可以配合我的代码做些实验,看看注释掉某个响应头会发生什么,整体代码会在最后贴出 跨域简单请求 需要在服务 ...

  3. 042.集群网络-flannel及calico

    一 Flannel组件 1.1 flannel介绍 Kubernetes的网络模型假定了所有Pod都在一个可以直接连通的扁平网络空间中.若需要实现这个网络假设,需要实现不同节点上的Docker容器之间 ...

  4. MyBatis框架——单表查询

    Mybatis单表查询,示例 1.创建数据库 /* Navicat MySQL Data Transfer Source Server : localhost Source Server Versio ...

  5. 试译 Understanding Delta-Sigma Modulators

         接触Σ-Δ调制的时候发现国内有关的资料比较匮乏,因为缺乏了解还有一些人把其中的原理吹得神乎其神难以理解.其实Σ-Δ调制的原理是很简单.逻辑上很自然的,可以定性理解成传统ADC/DAC量化的是 ...

  6. 动态规划-TSP问题-最短超级串

    2020-03-03 22:55:08 问题描述: 给定一个字符串数组 A,找到以 A 中每个字符串作为子字符串的最短字符串. 我们可以假设 A 中没有字符串是 A 中另一个字符串的子字符串. 示例 ...

  7. Building Applications with Force.com and VisualForce(Dev401)(十七):Data Management: Data management Tools

    ev401-018:Data Management: Data management ToolsModule Objectives1.List objects exposed in the impor ...

  8. coding++:java-HashMap的负载因子为什么默认是0.75?

    本篇文章基于JDK1.8,特在此说明 1):负载因子的作用 负载因子是和扩容机制有关的,意思是如果当前容器的容量,达到了我们设定的最大值,就要开始执行扩容操作.举个例子来解释,避免小白听不懂: 比如说 ...

  9. iOS 真机查看沙盒目录

    iExplorer 的方法试的时候设备都无法检测到,建议放弃 启用iTunes文件共享,才能够看沙盒内的文件,只需要在plist文件中添加如下信息: <key>UIFileSharingE ...

  10. SpringBoot使用RedisTemplate操作Redis时,key值出现 \xac\xed\x00\x05t\x00\tb

    原因分析 原因与RedisTemplate源码中的默认序列化方式有关 defaultSerializer = new JdkSerializationRedisSerializer( classLoa ...