线程案例锁的几种方法

来源:互联网 发布:如何安装sai软件 编辑:程序博客网 时间:2024/06/08 10:44
public class SaleBiz implements Runnable{
private int tickets = 100;
public void run() {
while(tickets>0){
System.out.println("窗口"+Thread.currentThread().getId()+"准备出票");
tickets = tickets-1;
System.out.println("窗口"+Thread.currentThread().getId()+"剩余车票"+tickets);
try {
Thread.sleep(200);
} catch (Exception e) {
// TODO: handle exception
}
}
}
1.public class SaleTest {
public static void testA(){//同一张票卖3次
 new Thread(new SaleBiz()).start();
 new Thread(new SaleBiz()).start();
 new Thread(new SaleBiz()).start();
}
2.public static void testB(){//三个线程共享一个对象run方法,一张票三个来抢
SaleBiz salebiz = new SaleBiz();
new Thread(salebiz).start();
new Thread(salebiz).start();
new Thread(salebiz).start();
}

出错三个线程都是先读再写,三个线程读取同一个数,但是存在时间差,写的时候一个已经改了,另一个还在用读的数字,资源不可能不变,所以要锁住资源。1.方法2.所对象3.所自身

public class SaleTicketSyn implements Runnable{
private Integer tickets = 100;
public void run() {
while(tickets>0){
1.//synchronized (tickets) {//不能锁基本类型的数据只能锁引用对象
2.//synchronized (tickets) {//在单位时间只能有一个线程可以使用tickets,其他线程排队
3.synchronized (this) {//锁代码块,锁定{}包含的代码块。锁定某个对象后,其它线程无法对这个对象再次加锁 (排他锁)

System.out.println("窗口"+Thread.currentThread().getId()+"准备出票");
tickets = tickets-1;
System.out.println("窗口"+Thread.currentThread().getId()+"剩余车票"+tickets);
try {
Thread.sleep(200);
} catch (Exception e) {
// TODO: handle exception
}}}}}

      public static void testC(){
SaleTicketSyn salebizsyn = new SaleTicketSyn();
new Thread(salebizsyn).start();
new Thread(salebizsyn).start();
new Thread(salebizsyn).start();
}

4.public class SaleTicket3 extends Thread{
LinkedList<Ticket> allTicket;
private long startTime;
public SaleTicket3(LinkedList<Ticket> allTicket,long startTime){
this.allTicket =allTicket;
this.startTime = startTime;
}
   public void run(){
 
  synchronized (allTicket) {
  while(allTicket.size()>0){ 
  System.out.println("窗口"+Thread.currentThread().getId()+"准备出票");
  allTicket.removeLast();
System.out.println("剩余车票"+allTicket.size());
try {
Thread.sleep(200);
} catch (Exception e) {
// TODO: handle exception
}
}
  double aa =(double) (System.currentTimeMillis()- startTime)/1000;
  System.out.println("一共耗时"+aa+"秒");

  }   
   } 
}

public static void testD(){
LinkedList<Ticket> allTicket = new LinkedList<Ticket>();
for(int i = 0;i<100;i++){
Ticket t = new Ticket("t"+i);
allTicket.add(t);
}

计算效率问题
long startTime =System.currentTimeMillis();
Thread t1 = new SaleTicket3(allTicket,startTime);
t1.start();
Thread t2 = new SaleTicket3(allTicket,startTime);
t2.start();
Thread t3 = new SaleTicket3(allTicket,startTime);//锁票,将票作为每个线程的入参
t3.start();

}

public static void main(String[] args) {
//SaleTest.testA();

//SaleTest.testB();

               //SaleTest.testC();

              SaleTest.testD();

}
}}