java多线程售票小例子

java多线程售票小例子

1、错误示范

class SellThread implements Runnable {
    private int i = 20;

    public void run() {
        while(true) {
            if(i > 0) {
                try {
                    Thread.sleep(100);
                } catch(Exception e) {

                }
                System.out.println(Thread.currentThread().getName() + "sell " + i--);   
            }
        }
    }
}

public class Test {

    public static void main(String[] args) {
        SellThread sell = new SellThread();
        Thread sell1 = new Thread(sell, "sellman1");
        Thread sell2 = new Thread(sell, "sellman2");
        Thread sell3 = new Thread(sell, "sellman3");
        sell1.start();
        sell2.start();      
        sell3.start();
    }
}

没有同步控制变量,所以最后出现了-1张票

java多线程售票小例子_第1张图片


2、正确示范

class SellThread implements Runnable {
    private int i = 20;
    String key = "";

    public void run() {
        while(true) {
            synchronized(key) {
                if(i > 0) {
                    try {
                    Thread.sleep(100);
                    } catch(Exception e) {

                    }
                    System.out.println(Thread.currentThread().getName() + "sell " + i--);   
                }else {
                    break;
                }
            }
        }
    }
}

public class Test {

    public static void main(String[] args) {
        SellThread sell = new SellThread();
        Thread sell1 = new Thread(sell, "sellman1");
        Thread sell2 = new Thread(sell, "sellman2");
        Thread sell3 = new Thread(sell, "sellman3");
        sell1.start();
        sell2.start();      
        sell3.start();
    }
}

java多线程售票小例子_第2张图片


补充:如果用synchronized关键字修饰方法,则只能有一个线程获取访问这段方法的权限。也就是说,一个线程把票买完了才结束。

class SellThread implements Runnable {
    private int i = 20;
    String key = "";

    public synchronized void run() {
        while(true) {
            if(i > 0) {
                try {
                    Thread.sleep(100);
                    } catch(Exception e) {

                    }
                    System.out.println(Thread.currentThread().getName() + "sell " + i--);                       
            }else {
                break;
            }
        }
    }
}

public class Test {

    public static void main(String[] args) {
        SellThread sell = new SellThread();
        Thread sell1 = new Thread(sell, "sellman1");
        Thread sell2 = new Thread(sell, "sellman2");
        Thread sell3 = new Thread(sell, "sellman3");
        sell1.start();
        sell2.start();      
        sell3.start();
    }
}

java多线程售票小例子_第3张图片

总结:

1、synchronized()括号中需要的是一个对象,所以这里使用了String类的一个对象key,可以用this来代替key。

2、一个线程拿到synchronized括号中的对象以后,其他线程也是可以执行的,但是当它们需要用key的时候,发现key已经被别人拿走了,只能等着key被释放了。就像上厕所,坑被别人占了,只能等着了,但是等着的时候我还可以运行,比如玩玩手机什么的。

3、synchronized method(){} 可以防止多个线程同时访问这个对象的synchronized方法;如果一个对象A,有多个synchronized方法,只要一个线程访问了其中的一个,那么其他线程不能同时访问A的任何一个synchronized方法。但是可以访问对象B的synchronized方法。

4、synchronized static method(){} 可以防止多个线程同时访问这个的synchronized方法;对类的所有对象均起作用,无论对象A、对象B、对象C的。

关于3、4,请参考 http://www.cnblogs.com/yanghuahui/p/3365922.html

java多线程售票小例子_第4张图片

你可能感兴趣的:(基础知识,Java,Java基础学习)