多线程--简单的卖票例子--基础

package com.lm.multest;
/*
 * 通过分析,发现,打印出0,-1,-2等错票。
 * 多线程的运行出现了安全问题。
 * 
 * 分析:
 * 问题的原因:
 *         当多条语句在操作同一个线程共享数据时,一个线程对多条语句只执行了一部分,还没有执行完
 *         另一个线程参与进来执行。导致共享数据错误。
 * 
 * 解决办法:
 *         对多条操作共享数据的语句,只能让一个线程执行完,在执行过程中,其他线程不可以参与执行。
 * 
 * Java对于多线程的安全问题提供了专业的解决的方式。
 * 
 * 就是同步代码块。
 * 
 * synchronized(对象)
 * {
 *         需要被同步的代码(那些语句在操作共享数据)
 * }
 * 对象如同锁。持有锁的线程可以在同步中执行。
 * 没有持有锁的线程即使获取cpu的执行权,也进不去,因为没有获取锁。
 * 
 * 火车上的卫生间---经典例子。
 * 
 * 
 * 同步的前提:
 * 1、必须要有两个或者两个以上的线程。
 * 2、必须是多个线程使用同一个锁。
 * 
 * 必须保证同步中只能有一个线程在运行。
 * 
 * 好处:解决了多线程的安全问题。
 * 弊端:多个线程都需要判断锁,教为消耗资源。
 * 
 *  同步函数用的是哪一个锁呢?
 * 函数需要被对象调用。那么函数都有一个所属对象引用。就是this。
 * 所以同步函数使用的锁是this。
 * 
 * */
class Ticket implements Runnable{

    private int num = 100;
    Object obj = new Object();
    boolean flag = true;
    @Override
    public void run() {
        if(flag){
            while(true){
                synchronized(this){ //判断锁,会消耗资源,同一个锁this
                    if(num>0){
                        System.out.println(Thread.currentThread().getName()+"  "+num--);
                    }
                }
            }
        }else{
            while(true)
                show();
        }
    }
    private synchronized void show(){
        if(num>0){
            System.out.println(Thread.currentThread().getName()+"  "+num--);
        }
    }
}

public class MulOne {

    public static void main(String[] args) {
        Ticket t = new Ticket();
        Thread a = new Thread(t);
        Thread b = new Thread(t);
        a.start();
        try {
            Thread.sleep(100);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        t.flag = false;
        b.start();
    }
}

  

posted @ 2013-08-26 15:25  微风夜明  阅读(247)  评论(0编辑  收藏  举报