多线程——引入同步代码块解决窗口卖票产生负票的问题

/**
 * 通过画图分析,分析上一篇博文中错票产生的原因:
 * 已经判断为票数了,线程被阻塞了,先一次被切换到不需要判断了。
 * 局部变量不会出现数字错乱的现象,而成员变量会出现数组出现负数的现象。
 * 
 * 安全的问题产生的原因:
 * 1.多个线程在操作共享数据。
 * 2.操作共享数据的代码有多条。
 * 
 * 一个线程在执行多条操作共享数据的过程当中,其他线程参与的运算,这时就会产生安全问题。
 * 
 * 想要分析线程当中是否有安全问题?
 * 依据:线程任务当中有没有共享的数据,该数据是否被多条语句操作。
 * 
 * 这个安全问题的解决方案?
 * 只要保证一个线程在执行多条共享数据的语句时,其他的线程不能参与运算即可。
 * 当该线程执行完之后,其他线程在来处理这个语句。
 * 
 * 代码体现:
 *    java给我们提供了具体的代码:就是同步代码块。
 *    格式:synchronized(对象){    //这个对象可以是任意的对象
 *            //需要被同步执行的语句
 *        }
 *
 * 同步的原理:其实就是将需要同步的代码进行了封装,然后在将封装的代码块之上加了一把锁。
 * 
 * 同步的好处:解决了多线程的安全问题。
 * 同步的弊端:会降低性能。
 * 
 * 一种现象,出现了多线程的安全性问题,为了解决加了同步,发现问题依旧,产生这个现象的原因是什么?
 * 
 * 同步的前提
 * 1.必须要保证同步中有多个线程,因为同步中只有一个线程这个同步是没有任何意义的。
 *   还需要注意把共享数据的多条代码都放在同步代码块当中。
 * 2.必须要保证多线程在同步中使用的是同一把锁。
 * 
 * */


package com.work.wor01;

class Ticket1 implements Runnable{
	private int num = 100;
	Object obj = new Object();
	@Override
	public void run() {
		while(true){
			synchronized (obj) {//同步代码块 , 解决了因为下面两行sleep()产生的产生负票问题。
				if(num>0){
					try {
//					在指定的毫秒数加指定的纳秒数内让当前正在执行的线程休眠(暂停执行)会产生负数票
						Thread.sleep(10);
					} catch (InterruptedException e) {
						e.printStackTrace();
					}
					System.out.println(Thread.currentThread().getName()+"...sale"+num--);
				}else{
					break;
				}
			}
			
		}
	}
} 

public class ThreadTicket02 {
	public static void main(String[] args) {
		Ticket1 t = new Ticket1();
		//Thread类的对象和Thread类的子类的对象都是线程的对象。
		//但是t并不是线程的对象。
		//向四个线程当中传入的是同一个t对象,是因为线程执行的是同样的任务。
		Thread t1 = new Thread(t);
		Thread t2 = new Thread(t);
		Thread t3 = new Thread(t);
		Thread t4 = new Thread(t);
		
		t1.start();
		t2.start();
		t3.start();
		t4.start();
	}
}

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值