第一种,从结果看来,编号并非随着线程的逐一增加而增加,也意味着不同的人,有的人先抢票,可是线程没有及时运行,抢到票或者买到剩票。
原因: 虽然方法是加锁了,但是不同的线程运行不确定的,而实际上对这个 票号的生成 并没有加锁限制,导致先买者,抢不到票。----- 票号不重复,但是没有优先概念,不连续。
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