先看再点赞,给自己一点思考的时间,如果对自己有帮助,微信搜索【程序职场】关注这个执着的职场程序员。
我有什么:职场规划指导,技能提升方法,讲不完的职场故事,个人成长经验。

大周末的还是6点起床,起床的第一件事就是打开电脑,因为昨天下班晚,回去看了会书就休息了,本来今天是可以有一个休息时间的,结果项目出了点小意外,还要去加班,你说心塞不心塞。

公众号的文章都是中午时间整理,晚上再编辑发布的,昨天时间太紧,就改成今天早上了。

今天我就像聊一个小知识点,线程同步。

废话不多说,先说概念,小伙伴先想想你的理解。

java线程的同步有一个关键词synchronize从英译过来是 "同时发生"。但其真正的含义和字面意思截然相反。线程同步的真实意思,其实是“排队”:几个线程之间要排队,一个一个对共享资源进行操作,而不是同时进行操作。

使用线程同步的目的:
是让各个线程去排队使用资源,而不是让线程同时去使用资源

概念只是让我们明白这个东西是干什么的,但是怎么做,具体怎么使用需要通过实例来说明。

对于线程同步我们生活中就有一个很好的例子就是买车票.

你看全国这么多人买票,不同的方式是(车站,携程,12306,代理窗口),车票肯定不是无限的,但是怎么做到让票卖出去,不会出现漏卖和空卖,怎么做到车票同步的呢?

1, 不同步

为了对比我们先来看看 如果 不是同步卖票  会出现什么情况?

public class ThreadSyn implements Runnable{
//有5张票
int ticked = 5;
@Override
//重写run()方法
public void run() {
for(int i=ticked;i>0;i--) {
System.out.println(Thread.currentThread().getName() + " sells " + i + " ticket");
}
}
//main方法测试
public static void main(String[] args) {
//实例化Thread对象
ThreadSyn tT = new ThreadSyn();
Thread td1 = new Thread(tT,"火车站");
Thread td2 = new Thread(tT,"携程");
Thread td3 = new Thread(tT,"代理商");
Thread td4 = new Thread(tT,"12306");
//启动线程
td1.start();
td2.start();
td3.start();
td4.start();
}
}
 

输入结果:
火车站 sells 5 ticket
携程 sells 5 ticket
携程 sells 4 ticket
火车站 sells 4 ticket
火车站 sells 3 ticket
火车站 sells 2 ticket
火车站 sells 1 ticket
携程 sells 3 ticket
携程 sells 2 ticket
携程 sells 1 ticket
代理商 sells 5 ticket
代理商 sells 4 ticket
代理商 sells 3 ticket
代理商 sells 2 ticket
代理商 sells 1 ticket
12306 sells 5 ticket
12306 sells 4 ticket
12306 sells 3 ticket
12306 sells 2 ticket
12306 sells 1 ticket

Process finished with exit code 0

结果优点崩溃,一共剩余5张票了,但是四个不同的方式,每一个竟然都能买到5张,这是不是有点乱了。

所以就有了同步的概念,当A在买票的时候,B在等待,A买完以后 系统同步票数,直到C去买票的时候,发现没有票了。

public class ThreadSyn implements Runnable{

    int ticket = 8;
//担任"锁",锁是什么不重要,他只是一把锁
//要求,非空对象
private String mutex = "";
@Override
//重写run()方法
public void run() {
//while循环
while (true) {
synchronized (mutex) {
if(ticket > 0) {
System.out.println(Thread.currentThread().getName()+ " sells " + ticket-- + " ticket.");
}else {
break;
}
}
}
}
//main方法测试
public static void main(String[] args) {
//实例化Thread对象
ThreadSyn tT = new ThreadSyn();
Thread td1 = new Thread(tT,"火车站");
Thread td2 = new Thread(tT,"携程");
Thread td3 = new Thread(tT,"代理商");
Thread td4 = new Thread(tT,"12306");
//启动线程
td1.start();
td2.start();
td3.start();
td4.start();
}
}
 

携程 sells 8 ticket.
携程 sells 7 ticket.
携程 sells 6 ticket.
携程 sells 5 ticket.
携程 sells 4 ticket.
携程 sells 3 ticket.
携程 sells 2 ticket.
携程 sells 1 ticket.

Process finished with exit code 0

结果可以添加了同步后,只卖了现有8张票,买完为止。

本文 Github ( 码云Gitee同步) https://github.com/ProceduralZC/JavaDevGuide/tree/master/code/JavaTheead/ThreadSynchron  已收录,欢迎 star。

我是【尔东双月】一枚执着的职场程序员,微信搜索【程序职场】关注我。别忘了三连啊,点赞、收藏、留言,随意给,我不挑。
知乎号: 程序职场
注:如果文章有任何问题,欢迎毫不留情地指正。

你知道购买车票的原理吗?Java 线程同步的更多相关文章

  1. java 线程同步 原理 sleep和wait区别

    java线程同步的原理java会为每个Object对象分配一个monitor, 当某个对象(实例)的同步方法(synchronized methods)被多个线程调用时,该对象的monitor将负责处 ...

  2. Java线程同步之一--AQS

    Java线程同步之一--AQS 线程同步是指两个并发执行的线程在同一时间不同时执行某一部分的程序.同步问题在生活中也很常见,就比如在麦当劳点餐,假设只有一个服务员能够提供点餐服务.每个服务员在同一时刻 ...

  3. Java线程同步_1

    Java线程同步_1 synchronized 该同步机制的的核心是同步监视器,任何对象都可以作为同步监视器,代码执行结束,或者程序调用了同步监视器的wait方法会导致释放同步监视器 synchron ...

  4. java线程 同步临界区:thinking in java4 21.3.5

    java线程 同步临界区:thinking in java4 21.3.5 thinking in java 4免费下载:http://download.csdn.net/detail/liangru ...

  5. JAVA - 线程同步和线程调度的相关方法

    JAVA - 线程同步和线程调度的相关方法 wait():使一个线程处于等待(阻塞)状态,并且释放所持有的对象的锁:wait是Object类的方法,对此对象调用wait方法导致本线程放弃对象锁,进入等 ...

  6. Java线程同步的四种方式详解(建议收藏)

    ​ Java线程同步属于Java多线程与并发编程的核心点,需要重点掌握,下面我就来详解Java线程同步的4种主要的实现方式@mikechen 目录 什么是线程同步 线程同步的几种方式 1.使用sync ...

  7. 从使用到原理学习Java线程池

    线程池的技术背景 在面向对象编程中,创建和销毁对象是很费时间的,因为创建一个对象要获取内存资源或者其它更多资源.在Java中更是如此,虚拟机将试图跟踪每一个对象,以便能够在对象销毁后进行垃圾回收. 所 ...

  8. Java 线程同步组件 CountDownLatch 与 CyclicBarrier 原理分析

    1.简介 在分析完AbstractQueuedSynchronizer(以下简称 AQS)和ReentrantLock的原理后,本文将分析 java.util.concurrent 包下的两个线程同步 ...

  9. 【转载】从使用到原理学习Java线程池

    线程池的技术背景 在面向对象编程中,创建和销毁对象是很费时间的,因为创建一个对象要获取内存资源或者其它更多资源.在Java中更是如此,虚拟机将试图跟踪每一个对象,以便能够在对象销毁后进行垃圾回收. 所 ...

随机推荐

  1. GO学习-(4) Go语言基础之变量和常量

    Go语言基础之变量和常量 变量和常量是编程中必不可少的部分,也是很好理解的一部分. 标识符与关键字 标识符 在编程语言中标识符就是程序员定义的具有特殊意义的词,比如变量名.常量名.函数名等等. Go语 ...

  2. NVIDIA深度架构

    NVIDIA深度架构 本文介绍A100 GPU,NVIDIA Ampere架构GPU的重要新功能. 现代云数据中心中运行的计算密集型应用程序的多样性推动了NVIDIA GPU加速的云计算的爆炸式增长. ...

  3. 向量算子优化Vector Operation Optimization

    向量算子优化Vector Operation Optimization 查看MATLAB命令View MATLAB Command 示例显示Simulink编码器 ,将生成向量的块输出,设置为标量,优 ...

  4. NSight Compute 用户手册(下)

    主菜单 文件 新建项目使用"新建项目"对话框创建新的分析项目 4. Main Menu and Toolbar Information on the main menu and t ...

  5. ContOS8 使用yum安装MariaDB

    首先全部删除MySQL/MariaDB(若是首次安装可根据需要跳过此步) 若不清楚MySQL和MariaDB的关系请移步至 Mariadb百科 1.查看系统版本(以下任一命令即可). # cat /p ...

  6. Handler_read_*的总结

    在分析一个SQL的性能好坏时,除了执行计划,另外一个常看的指标是"Handler_read_*"相关变量. Handler_read_key Handler_read_first ...

  7. Selective Kernel Networks

    摘要:在标准的卷积神经网络(CNNs)中,每一层的人工神经元的感受野被设计成具有相同的大小.众所周知,视觉皮层神经元的感受野大小受刺激的调节,但在构建cnn时却很少考虑到这一点.我们在神经网络中提出了 ...

  8. UNREFERENCED_PARAMETER的用处

    UNREFERENCED_PARAMETER的用处 作用:告诉编译器,已经使用了该变量,不必检测警告! 在VC编译器下,如果您用最高级别进行编译,编译器就会很苛刻地指出您的非常细小的警告.当你生命了一 ...

  9. Android Gradle插件

    目录 什么是Gradle 编写方法 buildSrc 基础概念 Extension 自定义Task Plugin Transformer Gradle用处 好文章 常见问题 Gradle插件练习地址: ...

  10. 【题解】P2854 [USACO06DEC]牛的过山车Cow Roller Coaster

    P2854 [USACO06DEC]牛的过山车Cow Roller Coaster 题目描述 The cows are building a roller coaster! They want you ...