线程的并发

1.线程并发的产生

  这里举一个买票的经典案例:四个窗口售卖100涨车票,代码如下:

public class Ticket implements Runnable{
    /**线程名称*/
    private String name;
    /**车票库存*/
    static int tickets = 100;
    /**构造器*/
    public Ticket(String name){
        this.name = name;
    }
    @Override
    public void run(){
        while (true){
           if(tickets>0){
               System.out.println(name+"窗口正在售卖第"+(tickets--)+"张票");
           }else {
               break;
           }          
        }
        System.out.println(name+"窗口售完票");
    }
}

  运行后发现存在多个窗口成功售卖同一张票,这样不符合实际需求的情况就是线程的并发。

2.线程并发的解决

  使用synchronized关键字,语法如下:

 

synchronized(锁对象){
     //操作共享资源的代码      
}

 

  同步代码加在什么地方?

  (1)代码被多个线程访问;

  (2)代码中有共享的数据;

  (3)共享数据被多条语句操作;

  修改买票案例,代码如下:

public class Ticket implements Runnable{
    /**车票库存*/
    int tickets = 100;
    /**创建一个锁对象,这个对象有多个线程共同使用*/
    static Object obj = new Object();
    @Override
    public void run(){
        while (true){
            //多线程共享代码块
            synchronized (obj) {
                if (tickets > 0) {
                    System.out.println(Thread.currentThread().getName() + "窗口正在售卖第" + (tickets--) + "票");
                } else {
                    break;
                }
            }
        }
        System.out.println(Thread.currentThread().getName()+"窗口售完票");
    }

    public static void main(String args[]){
        Ticket ticket = new Ticket();
        Thread thread1 = new Thread(ticket,"窗口1");
        Thread thread2 = new Thread(ticket,"窗口2");
        Thread thread3 = new Thread(ticket,"窗口3");
        Thread thread4 = new Thread(ticket,"窗口4");

        thread1.start();
        thread2.start();
        thread3.start();
        thread4.start();
    }
}

  *注意:本次改造把整个Ticket类作为了共享对象

posted @ 2019-12-13 14:04  小小吸血鬼  阅读(273)  评论(0编辑  收藏  举报