解决存在的线程安全问题:打印车票时出现重票,错票

使用同步代码块的解决方案

TestWindow2

package com.aff.thread;
/*
使用实现Runnable接口的方式,售票
存在线程安全问题: 打印车票时出现重票,错票
1.原因:由于一个线程在操作共享数据过程中,未执行完毕的情况下,
另外的线程参与进来了,导致共享数据存在了安全问题
2.解决想法:让一个线程操作共享数据完毕后,其他进程才有机会参与共享数据的使用
3.java的解决方案:
线程的同步机制
方式一:同步代码块
synchronized(同步监视器){
//需要被同步的代码块(即为操作共享数据的代码)
}
1.共享数据:多个线程共同操作的同一个数据(变量)
2.同步监视器:由一个类的对象来充当,哪个线程获取此监视器,
谁就执行大括号里被同步的代码,俗称 "锁"
3.要求所有线程必须共用同一把锁
注意: 在实现的方式中,考虑同步的话,可以使用this充当锁。
但是在继承的方式中,慎用this
方式二:同步方法
将操作共享数据的方法声明为synchronized,
即此方法为同步方法,
能够保证当其中一个线程执行此方法时,
其他线程在外等待直至此线程执行完此方法。
注意:同步方法的锁为this
4.线程的同步的弊端:由于同一个时间只能有一个线程访问共享数据,效率变低了 */
public class TestWindow2 {
public static void main(String[] args) {
Window2 w = new Window2();
Thread t1 = new Thread(w);
Thread t2 = new Thread(w);
Thread t3 = new Thread(w); t1.setName("窗口1");
t2.setName("窗口2");
t3.setName("窗口3"); t1.start();
t2.start();
t3.start();
}
} class Window2 implements Runnable {
int ticket = 100;// 共享数据
//Object obj = new Object(); @Override
public void run() {
while (true) {
synchronized (this){//任何一个类的对象都可以来充当 ,习惯上使用this充当,指当前的对象,
//此处指的是w对象,若换成继承的方式实现多线程,
//那此处的this分别指的三个对象了,不是同一把锁,就解决不了安全性问题了
if (ticket > 0) {
try {
Thread.currentThread().sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + "售票,票号为:" + ticket--);
}
}
}
}
}

使用同步方法的解决方案

TestWindow4

package com.aff.thread;

public class TestWindow4 {
public static void main(String[] args) {
Window4 w = new Window4();
Thread t1 = new Thread(w);
Thread t2 = new Thread(w);
Thread t3 = new Thread(w); t1.setName("窗口1");
t2.setName("窗口2");
t3.setName("窗口3"); t1.start();
t2.start();
t3.start();
}
} class Window4 implements Runnable {
int ticket = 1000;// 共享数据 @Override
public void run() {
while (true) {
show();
}
} public synchronized void show() {
if (ticket > 0) {
try {
Thread.currentThread().sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + "售票,票号为:" + ticket--);
}
} }

锁的理解图

最新文章

  1. Premiere使用整理
  2. HTML5- Canvas入门(七)
  3. IE环境下判断IE版本的语句...[if lte IE 6]……[endif][if lte IE 7]……[endif]
  4. Flask 的扩展
  5. CSS中的class与id区别及用法
  6. Zero Requiem
  7. oracle视图总结
  8. POP3、SMTP和IMAP之间的区别和联系
  9. C语言中内存分配 (转)
  10. Repeater的ItemCommand事件和ItemCreated事件,高手请跳过~
  11. iOS体会篇 大学编程到公司的过程
  12. ssh命令大全
  13. sql server实现简繁转换
  14. netty编程一:快速入门
  15. Python一行代码处理地理围栏
  16. 题解——CF Manthan, Codefest 18 (rated, Div. 1 + Div. 2) T1(找规律)
  17. win10安装PS和AI后报代码为16的错误解决方法
  18. hdu 4920
  19. Pythoner使用的豆瓣pip源
  20. JS 对应CSS 样式

热门文章

  1. zabbix分布式安装全过程
  2. CSS设计超链接样式
  3. CSS3.16
  4. C. Helga Hufflepuff's Cup 树形dp 难
  5. leetcode485——最大连续1的个数(easy)
  6. Linux内核驱动学习(十)Input子系统详解
  7. JS实现手机号码中间4位变星号
  8. 1026 Table Tennis (30分) 难度不高 + 逻辑复杂 +细节繁琐
  9. 「雕爷学编程」Arduino动手做(36)——WS2812B 4位彩灯模块
  10. Python格式化字符串(格式化输出)