Thread-synchronized同步 -火车票实例
来源:互联网 发布:java native的用法 编辑:程序博客网 时间:2024/06/06 22:23
线程安全问题产生的原因:
1,多个线程在操作共享的数据。
2,操作共享数据的线程代码有多条。
当一个线程在执行操作共享数据的多条代码过程中,其他线程参与了运算。就会导致线程安全问题的产生。
解决思路;
就是将多条操作共享数据的线程代码封装起来,当有线程在执行这些代码的时候,其他线程时不可以参与运算的。
必须要当前线程把这些代码都执行完毕后,其他线程才可以参与运算。
在java中,用同步代码块就可以解决这个问题。
同步代码块的格式:
synchronized(对象){需要被同步的代码 ;}
同步的好处:解决了线程的安全问题。
同步的弊端:相对降低了效率,因为同步外的线程的都会判断同步锁。
同步的前提:同步中必须有多个线程并使用同一个锁。
例1:多个窗口购买火车票实例:
package day04;public class JavaTest { public static void main(String[] args) { SaleTicket st=new SaleTicket(); Thread t1=new Thread(st,"一号窗口"); Thread t2=new Thread(st,"二号窗口"); Thread t3=new Thread(st,"三号窗口"); Thread t4=new Thread(st,"四号窗口"); t1.start(); t2.start(); t3.start(); t4.start(); }}class SaleTicket implements Runnable{//sale英 [seɪl] n.拍卖;卖,出卖; private int tickets=100; @Override public void run() { while(tickets>0){ sale(); } } private synchronized void sale(){//synchronized 同步。 if(tickets>0){ System.out.println(Thread.currentThread().getName()+"卖出了第"+(100-tickets+1)+"张票"); tickets --; try{ Thread.sleep(500);//假设购票过程需要500毫秒。 }catch(InterruptedException e){ e.printStackTrace(); } } }}
运行结果:
一号窗口卖出了第1张票四号窗口卖出了第2张票二号窗口卖出了第3张票三号窗口卖出了第4张票三号窗口卖出了第5张票.................四号窗口卖出了第99张票四号窗口卖出了第100张票
例2: 创建两个线程t1和t2同时减桌子上的20颗豆子。至到豆子的数量减为0,人为抛出异常为止。这是桌上的豆子就是公共事件,两个线程会同时去访问。所以要加synchronized将公共资源同步的锁起来。
package day04;/** * 当多个线程同时操作一段数据时,由于线程切换的不确定性,可能会导致逻辑出现混乱。 * @author Administrator */public class SyncDemo { public static void main(String[] args) { final Table table = new Table(); Thread t1 = new Thread(){ public void run(){ while(true){ int bean = table.getBean(); //模拟CPU没有时间了 Thread.yield(); //yield英 [ji:ld] vi.放弃;退让,退位 System.out.println(getName()+":"+bean); } } }; Thread t2 = new Thread(){ public void run(){ while(true){ int bean = table.getBean(); Thread.yield(); //yield英 [ji:ld] vi.放弃;退让,退位 System.out.println(getName()+":"+bean); } } }; t1.start(); t2.start(); }}class Table{ private int beans = 20;//桌子上有20个豆子 /* * 当一个方法被synchronized修饰后,该方法 就是一个同步方法了。多个线程调用时不会同时进到方法内部。 * 需要注意的是synchronized一定会给一个对象上锁。在这里,锁的是当前方法所属的对象。 * 也就是上面main方法中创建的table实例。由于两个线程调用的是同一个table的getBean方法。所以两个线程不能同时进到方法内部。 */ public synchronized int getBean(){ if(beans==0){throw new RuntimeException("没有豆子了!");} Thread.yield(); return beans--; }}
运行结果:
Thread-1:20Thread-1:18Thread-1:17Thread-1:16Thread-1:15Thread-1:14Thread-1:13Thread-1:12Thread-1:11Thread-1:10Thread-1:9Thread-1:8Thread-1:7Thread-1:6Thread-1:5Thread-1:4Thread-1:3Thread-1:2Thread-1:1Thread-0:19Exception in thread "Thread-1" Exception in thread "Thread-0" java.lang.RuntimeException: 没有豆子了! at day04.Table.getBean(SyncDemo.java:41) at day04.SyncDemo$2.run(SyncDemo.java:22)java.lang.RuntimeException: 没有豆子了! at day04.Table.getBean(SyncDemo.java:41) at day04.SyncDemo$1.run(SyncDemo.java:12)
0 0
- Thread-synchronized同步 -火车票实例
- java多线程学习笔记(三) ——多线程实例火车票问题+同步synchronized初接触
- 多线程Thread同步synchronized(加锁)
- Thread安全之synchronized同步锁
- Synchronized (同步) block使用实例
- linux thread 同步 操作 实例
- synchronized 同步锁(java)实例解析
- synchronized Thread
- Thread - synchronized
- Thread - synchronized
- java synchronized:(实例方法同步、静态方法同步)区别
- java --thread--火车票售票系统
- 同步-synchronized
- synchronized同步
- 同步synchronized
- synchronized同步
- synchronized同步
- java多线程-多线程同步代码块-银行存款实例-锁synchronized
- 西瓜理发记(一)
- C#的自悟
- hdu 5233 Gunner II 离散化
- 极光推送(基础篇)
- struts-2.3.31和struts-2.5.10引入jar以及配置web.xml和struts.xml
- Thread-synchronized同步 -火车票实例
- jdk环境变量配置
- C#的转换方式
- 学习JavaScript闭包
- 20.Spark上下文构建以及模拟数据生成
- Spring面试,IoC和AOP的理解
- linux学习笔记(六)
- 对电子游戏的平衡性和可玩性的直观感受和对游戏生涯的憧憬
- java实现链表及其相关操作