关于对java多线程售票系统的理解,synchronized关键字

java多线程一直是学会java的关键,多线程中的同步则是安全性的保障,尽管效率会有所下降。为了理解synchronized 的用法,先把代码放上来

未使用synchronized关键字的代码

package thread;
public class ticket implements Runnable{
	public  int i=10;
	public void run() {
			while(true) {			
				  if(i>0) {					
						System.out.println(Thread.currentThread().getName()+":卖出一张票,当前还有:"+--i);														               
				           }
				  try {
						Thread.sleep(300);
					} catch (InterruptedException e) {
						// TODO 自动生成的 catch 块
						e.printStackTrace();
					}    		
					
			}		
				     
	}
		
			 
									
   public static void main(String[] args) {
	   ticket t=new ticket();
       for(int i=0;i<2;i++) {
    	   Thread s=new Thread(t,"线程"+(i+1));
    			   s.start();
       }
}
}


这一段没有使用同步块会产生一定的问题:
线程1:卖出一张票,当前还有:8
线程2:卖出一张票,当前还有:9
线程2:卖出一张票,当前还有:7
线程1:卖出一张票,当前还有:7
线程1:卖出一张票,当前还有:6
线程2:卖出一张票,当前还有:5
线程2:卖出一张票,当前还有:4
线程1:卖出一张票,当前还有:3
线程2:卖出一张票,当前还有:2
线程1:卖出一张票,当前还有:1
线程1:卖出一张票,当前还有:0
线程2:卖出一张票,当前还有:0
或者是
线程1:卖出一张票,当前还有:9
线程2:卖出一张票,当前还有:8
线程1:卖出一张票,当前还有:7
线程2:卖出一张票,当前还有:6
线程1:卖出一张票,当前还有:5
线程2:卖出一张票,当前还有:5
线程1:卖出一张票,当前还有:4
线程2:卖出一张票,当前还有:3
线程1:卖出一张票,当前还有:2
线程2:卖出一张票,当前还有:2
线程2:卖出一张票,当前还有:1
线程1:卖出一张票,当前还有:1
线程1:卖出一张票,当前还有:0
线程2:卖出一张票,当前还有:-1
会出现一张票进行了多次出售或者是把第零张票也卖了,这是因为线程的并发所产生的问题,两个线程同时进行了,我们要做的就是一个线程执行时,其他线程要进行等待,需要用到synchronized 关键字

下面添加同步块来解决这个问题




package thread;
public class ticket implements Runnable{
	public  int i=200;
	private Object obj=new Object();
	public void run() {
			while(true) {	
			//将线程执行的语句用synchronized关键字包括,并添加同步锁
				synchronized (obj) {
				  if(i>0) {					
						System.out.println(Thread.currentThread().getName()+":卖出一张票,当前还有:"+--i);														               
				           }
				  try {
						Thread.sleep(500);
					} catch (InterruptedException e) {
						// TODO 自动生成的 catch 块
						e.printStackTrace();
					}    		
					
			}		
		}
			
				     
	}
									
   public static void main(String[] args) {
	   ticket t=new ticket();
       for(int i=0;i<4;i++) {
    	   Thread s=new Thread(t,"线程"+(i+1));
    			   s.start();
       }
}
}

synchronized 这里用的是同步代码块,要为这个关键字设定一个同步锁,这个锁是可以任意的,但是要是这几个线程所共有的,所以我声明了一个object对象。

添加同步方法


package thread;
public class ticket implements Runnable{
	public  int i=200;
	private Object obj=new Object();
	public void run() {
			while(true) {	
				sell();					
			}		
		}
	private synchronized void sell() {
		 if(i>0) {					
				System.out.println(Thread.currentThread().getName()+":卖出一张票,当前还有:"+--i);														               
		           }
		  try {
				Thread.sleep(500);
			} catch (InterruptedException e) {
				// TODO 自动生成的 catch 块
				e.printStackTrace();
			}    		
	}
		
			 
									
   public static void main(String[] args) {
	   ticket t=new ticket();
       for(int i=0;i<4;i++) {
    	   Thread s=new Thread(t,"线程"+(i+1));
    			   s.start();
       }
}
}

把线程所要执行的代码进行封装,再用synchronized关键字修饰该函数(默认同步锁是this),最后再调用即可
由于我电脑cpu原因,要五百张票才能体现出线程,所以就不放结果了

synchronized修饰不论是同步块还是同步方法,只要有一个线程正在执行,那么这一部分就会锁死,不会出现线程并发的问题。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值