Java提供了线程同步的机制来防止资源访问的冲突。

1、线程安全

实际开发中,使用多线程程序的情况很多,如银行排号系统、火车站售票系统等。这种多线程的程序通常会发生问题。

以火车站售票系统为例,在代码中判断当前票数是否大于0,如果大于0则执行将该票出售给乘客功能,但当两个线程同时访问这段代码时(假如这时只剩下一张票),第一个线程将票售出,与此同时第二个线程也已经执行完成判断是否有票的操作,并得出结论票数大于0,于是它也执行售出操作,这样就会产生负数。所以在编写多线程程序时,应该考虑到线程安全问题。实质上线程安全问题来源于两个线程同时存取单一对象的数据。

例如:在项目中创建ThreadSafeTest类,该类实现了Runnable接口,主要实现模拟火车站售票系统的功能。

public class ThreadSafeTest implements Runnable {int num = 10; // 设置当前总票数public void run() {while (true) {if (num > 0) {try {Thread.sleep(100);} catch (Exception e) {e.printStackTrace();}System.out.println("tickets" + num--);}}}public static void main(String[] args) {ThreadSafeTest t = new ThreadSafeTest(); // 实例化类对象Thread tA = new Thread(t); // 以该类对象分别实例化4个线程Thread tB = new Thread(t);Thread tC = new Thread(t);Thread tD = new Thread(t);tA.start(); // 分别启动线程
        tB.start();tC.start();tD.start();}
}

从运行结果中看出,最后售的票为负值,这样就出现了问题。这是由于同时创建了4个线程,这4个线程执行run()方法,在num变量为1时,线程1、线程2、线程3、线程4都对num变量有存储功能,当线程1执行run()方法时,还没来得及做递减操作,就指定它调用sleep()方法进入休眠状态,这时线程2、线程3和线程4都进入了run()方法,发现num变量依然大于0,但此时线程1休眠时间已到,将num变量递减,同时线程2、线程3、线程4也都对num变量进行递减操作,从而产生了赋值。

2、线程同步机制

基本上所有解决多线程资源冲突问题的方法都是采用给定时间允许一个线程访问共享资源,这时就需要给共享资源上一道锁。这就好比一个人上洗手间时,他进入洗手间后会将门锁上,出来时再将锁打开,然后其他人才可以进入。

(1)同步块

在Java中提供了同步机制,可以有效第防止资源冲突。同步机制使用synchronized关键字。将资源放在同步块中,这个同步块被称为临界区。

synchronized(Object){
}

通常将共享资源的操作放置在synchronized定义的区域内,这样当其他线程也获取到这个锁时,必须等待锁被释放时才能进入该区域。Object为任意一个对象,每个对象都存在一个标志位,并具有两个值,分别为0和1。一个线程运行到同步块时首先检查对象的标志位,如果为0状态,表明此同步块中存在其他线程在运行。这时该线程处于就绪状态,直到处于同步块中的线程执行完同步块中的代码为止。这时该对象的标识位被设置为1,该线程才能执行同步块中的代码,并将Object对象的标识位设置为0,防止其他线程执行同步块中的代码。

例如:在本实例中,创建类ThreadSafeTest.java,在该类中修改上述中run()方法,把对num操作的代码设置在同步块中。

public class ThreadSafeTest implements Runnable {int num = 10;public void run() {while (true) {synchronized ("") {if (num > 0) {try {Thread.sleep(1000);} catch (Exception e) {e.printStackTrace();}System.out.println("tickets" + --num);}}}}public static void main(String[] args) {ThreadSafeTest t = new ThreadSafeTest();Thread tA = new Thread(t);Thread tB = new Thread(t);Thread tC = new Thread(t);Thread tD = new Thread(t);tA.start();tB.start();tC.start();tD.start();}
}

(2)同步方法

同步方法就是在方法前面修饰synchronized关键字的方法,其语法如下:

synchronized  void f(){
}

当某个对象调用了同步方法时,该对象上的其他同步方法必须等待该同步方法执行完毕后才能被执行。

第18章 多线程----线程同步相关推荐

  1. Java7并发编程指南——第三章:线程同步辅助类

    Java7并发编程指南--第三章:线程同步辅助类 @(并发和IO流) Java7并发编程指南第三章线程同步辅助类 思维导图 项目代码 思维导图 项目代码 GitHub:Java7Concurrency ...

  2. Java7并发编程指南——第二章:线程同步基础

    Java7并发编程指南--第二章:线程同步基础 @(并发和IO流) Java7并发编程指南第二章线程同步基础 思维导图 项目代码 思维导图 项目代码 GitHub:Java7ConcurrencyCo ...

  3. java同步与死锁_Java多线程 - 线程同步与死锁

    一.线程同步 1)模拟多个用户同时从银行账户里面取钱 ● Account 类:银行账户类,里面有一些账户的基本信息,以及操作账户信息的方法 //模拟银行账户 classAccount {private ...

  4. C#中的多线程-线程同步基础 (控制线程数量)

    同步要领 下面的表格列展了.NET对协调或同步线程动作的可用的工具: 简易阻止方法 构成 目的 Sleep 阻止给定的时间周期 Join 等待另一个线程完成 锁系统 构成 目的 跨进程? 速度 loc ...

  5. 9 C++ Boost 多线程,线程同步

    线程的创建 boost_thread,boost_system 多线程的创建 线程的参数传递 线程的创建方式 线程的join 加入join,回收线程线程中断 线程中断2, 线程组 boost 线程的死 ...

  6. JAVA-初步认识-第十三章-多线程(验证同步函数的锁)

    一. 至于同步函数用的是哪个锁,我们可以验证一下,借助原先卖票的例子 对于程序中的num,从100改为400,DOS的结果显示的始终都是0线程,票号最小都是1. 票号是没有问题的,因为同步了. 有人针 ...

  7. Python多线程——线程同步

    创建多线程 继承Thread类创建派生类,并重写__init__和run方法,实现自定义线程对象类: import threading import timeclass myThread(thread ...

  8. Java 多线程 线程同步

    线程同步 1.发生在多个线程操作同一个资源 2.并发:同一个对象被多个线程同时操作 3.于是,就需要线程同步.线程同步其实就是一种等待机制,多个需要同时访问此对象的线程进入这个对象的等待池形成队列,等 ...

  9. 13-多线程01 实现多线程 线程同步 生产者消费者

    1.实现多线程 1.1简单了解多线程[理解] 是指从软件或者硬件上实现多个线程并发执行的技术. 具有多线程能力的计算机因有硬件支持而能够在同一时间执行多个线程,提升性能. 1.2并发和并行[理解] 并 ...

最新文章

  1. stm32万年历流程图_STM32实现万年历..
  2. 彩色图像--色彩空间 YIQ 、YUV 、YCbCr 、YC1C2 和I1I2I3
  3. linux内核使用scons构建,如何使用scons进行交叉构建
  4. php中的__autoload()函数
  5. 14.parfor并行循环处理
  6. 什么叫返回路径平面上的间隙_差分信号回流路径的全波电磁场解析
  7. Antechinus C# Editor!
  8. linux查看主机硬件命令
  9. 小米平板5最快有望7月发布:骁龙870/天玑12002K双版本
  10. 【多线程】CountDownLatch 和 CyclicBarrier:如何让多线程步调一致?
  11. 管理数据,应用程序和主机安全-A
  12. python上机实践_python程序设计江红上机实践答案
  13. 圆弧周长公式_扇形面积和周长计算公式 【关于扇形的所有公式(周长、弧长、半径、圆心角)写得清楚、详细......
  14. 计算机管理员绩效指标,网络管理员绩效kpi考核标准..doc
  15. 解决Windows Update错误“80072EFD”
  16. drools 6.5 决策表使用
  17. js实现开平方 Math.sqrt
  18. 高德地图添加Marker点标记
  19. CAXA 2020电子图板设计从入门到精通视频教程
  20. 计算机保研面试题——计算机网络

热门文章

  1. jQuery学习笔记——jQuery选择器详解种类与方法
  2. php 面向对象开发 类的学习 一
  3. C 一个数组删除一项 并且移位
  4. Repeater控件的使用
  5. C#拾遗系列(3):构造函数
  6. (原創) 為什麼企業研發喜歡找研究生? (日記)
  7. [ZJOI2011]细胞——斐波那契数列+矩阵加速+dp
  8. 《C#多线程编程实战(原书第2版)》——第3章 使用线程池 3.1 简介
  9. maven详解之生命周期与插件
  10. VirtualBox的四种网络连接方式