将线程锁加在对象上与锁加在方法上的区别(模拟火车票联网售票系统:多个线程同时出票,保证每张出票的编号连续且不重复。)...

  第一种,从结果看来,编号并非随着线程的逐一增加而增加,也意味着不同的人,有的人先抢票,可是线程没有及时运行,抢到票或者买到剩票。

  原因: 虽然方法是加锁了,但是不同的线程运行不确定的,而实际上对这个 票号的生成  并没有加锁限制,导致先买者,抢不到票。----- 票号不重复,但是没有优先概念,不连续。

ticketNum: 5 Thread Name: Thread 1  线程1 先启动并调用生成票方法, 之后得到5号票
ticketNum: 8 Thread Name: Thread 8
ticketNum: 7 Thread Name: Thread 7
ticketNum: 1 Thread Name: Thread 3
ticketNum: 10 Thread Name: Thread 10
ticketNum: 0 Thread Name: Thread 0
ticketNum: 4 Thread Name: Thread 2
ticketNum: 6 Thread Name: Thread 6
ticketNum: 2 Thread Name: Thread 5 
package test;

public class Starter {

	public static void main(String[] args) {
		for(int i=0;i<50;i++){
			BookTicketThread book=new BookTicketThread("Thread "+i);
		}
	}

}

package test;

public class BookTicketThread extends Thread{
	
	private String name;
	private Data data;
	
	public BookTicketThread(String name){
		this.name=name;
		//this.data=data;
		start();
	}

	@Override
	public void run() {
			System.out.println("ticketNum: "+Data.getTicketNum()+" Thread Name: "+name);   // Data.getTicketNum 方法被锁住,这时候调用该方法的可能是任意一个线程,所有线程都有相同的竞争权利。所以1号线程 可能被迫得到五号票。
	}

}

package test;

public class Data{
	
	private static int ticketNum;
	
	public synchronized static int getTicketNum(){
		return ticketNum++;
	}

}



result:
ticketNum: 5 Thread Name: Thread 1
ticketNum: 8 Thread Name: Thread 8
ticketNum: 7 Thread Name: Thread 7
ticketNum: 1 Thread Name: Thread 3
ticketNum: 10 Thread Name: Thread 10
ticketNum: 0 Thread Name: Thread 0
ticketNum: 4 Thread Name: Thread 2
ticketNum: 6 Thread Name: Thread 6
ticketNum: 2 Thread Name: Thread 5
ticketNum: 13 Thread Name: Thread 13
ticketNum: 3 Thread Name: Thread 4
ticketNum: 14 Thread Name: Thread 14
ticketNum: 12 Thread Name: Thread 12
ticketNum: 11 Thread Name: Thread 11
ticketNum: 16 Thread Name: Thread 16
ticketNum: 9 Thread Name: Thread 9
ticketNum: 17 Thread Name: Thread 17
ticketNum: 18 Thread Name: Thread 18
ticketNum: 15 Thread Name: Thread 15
ticketNum: 19 Thread Name: Thread 19
ticketNum: 20 Thread Name: Thread 20
ticketNum: 21 Thread Name: Thread 21
ticketNum: 22 Thread Name: Thread 22
ticketNum: 23 Thread Name: Thread 23
ticketNum: 24 Thread Name: Thread 24
ticketNum: 25 Thread Name: Thread 25
ticketNum: 26 Thread Name: Thread 26
ticketNum: 27 Thread Name: Thread 27
ticketNum: 28 Thread Name: Thread 28
ticketNum: 29 Thread Name: Thread 29
ticketNum: 30 Thread Name: Thread 30
ticketNum: 31 Thread Name: Thread 31
ticketNum: 32 Thread Name: Thread 32
ticketNum: 33 Thread Name: Thread 33
ticketNum: 34 Thread Name: Thread 34
ticketNum: 35 Thread Name: Thread 35
ticketNum: 36 Thread Name: Thread 36
ticketNum: 37 Thread Name: Thread 37
ticketNum: 38 Thread Name: Thread 38
ticketNum: 39 Thread Name: Thread 39
ticketNum: 40 Thread Name: Thread 40
ticketNum: 41 Thread Name: Thread 41
ticketNum: 42 Thread Name: Thread 42
ticketNum: 43 Thread Name: Thread 43
ticketNum: 44 Thread Name: Thread 44
ticketNum: 45 Thread Name: Thread 45
ticketNum: 46 Thread Name: Thread 46
ticketNum: 47 Thread Name: Thread 47
ticketNum: 48 Thread Name: Thread 48
ticketNum: 49 Thread Name: Thread 49

  

 

方法二: 锁住对象,正所谓要得到优先权,锁住方法不能保持得到结果的先后顺序,需要将整个对象锁定,来得到结果才可以保证结果的有序。

package test;

public class Starter {

	public static void main(String[] args) {
		Data data=new Data();
		for(int i=0;i<50;i++){
			BookTicketThread book=new BookTicketThread("Thread "+i,data);
		}
	}

}

package test;

public class BookTicketThread extends Thread{
	
	private String name;
	private Data data;
	
	public BookTicketThread(String name,Data data){
		this.name=name;
		this.data=data;
		start();
	}

	@Override
	public void run() {
			System.out.println("ticketNum: "+data.getTicketNum()+" Thread Name: "+name);
	}

}

package test;

public class Data{
	
	private  int ticketNum;
	
	public synchronized  int getTicketNum(){
		return ticketNum++;
	}

}

  result: 连续 且不重复。

ticketNum: 0 Thread Name: Thread 0
ticketNum: 4 Thread Name: Thread 4
ticketNum: 3 Thread Name: Thread 3
ticketNum: 2 Thread Name: Thread 2
ticketNum: 6 Thread Name: Thread 6
ticketNum: 1 Thread Name: Thread 1
ticketNum: 7 Thread Name: Thread 7
ticketNum: 5 Thread Name: Thread 5
ticketNum: 8 Thread Name: Thread 8
ticketNum: 9 Thread Name: Thread 9
ticketNum: 10 Thread Name: Thread 10
ticketNum: 11 Thread Name: Thread 11
ticketNum: 12 Thread Name: Thread 12
ticketNum: 13 Thread Name: Thread 13
ticketNum: 14 Thread Name: Thread 14
ticketNum: 15 Thread Name: Thread 15
ticketNum: 16 Thread Name: Thread 16
ticketNum: 17 Thread Name: Thread 17
ticketNum: 18 Thread Name: Thread 18
ticketNum: 19 Thread Name: Thread 19
ticketNum: 20 Thread Name: Thread 20
ticketNum: 21 Thread Name: Thread 21
ticketNum: 22 Thread Name: Thread 22
ticketNum: 23 Thread Name: Thread 23
ticketNum: 24 Thread Name: Thread 24
ticketNum: 25 Thread Name: Thread 25
ticketNum: 26 Thread Name: Thread 26
ticketNum: 27 Thread Name: Thread 27
ticketNum: 28 Thread Name: Thread 28
ticketNum: 29 Thread Name: Thread 29
ticketNum: 30 Thread Name: Thread 30
ticketNum: 31 Thread Name: Thread 31
ticketNum: 32 Thread Name: Thread 32
ticketNum: 33 Thread Name: Thread 33
ticketNum: 34 Thread Name: Thread 34
ticketNum: 35 Thread Name: Thread 35
ticketNum: 36 Thread Name: Thread 36
ticketNum: 37 Thread Name: Thread 37
ticketNum: 38 Thread Name: Thread 38
ticketNum: 39 Thread Name: Thread 39
ticketNum: 40 Thread Name: Thread 40
ticketNum: 41 Thread Name: Thread 41
ticketNum: 42 Thread Name: Thread 42
ticketNum: 43 Thread Name: Thread 43
ticketNum: 44 Thread Name: Thread 44
ticketNum: 45 Thread Name: Thread 45
ticketNum: 46 Thread Name: Thread 46
ticketNum: 47 Thread Name: Thread 47
ticketNum: 48 Thread Name: Thread 49
ticketNum: 49 Thread Name: Thread 48

 

转载于:https://www.cnblogs.com/IamThat/p/4339924.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值