day23--电影院买票问题解决 同步代码块 同步方法 静态同步方法的引入

package cn.itcast_11;

/*
 * A:同步代码块的锁对象是谁呢?
 *         任意对象。
 *
 * B:同步方法的格式及锁对象问题?
 *         把同步关键字加在方法上。
 *
 *         同步方法的锁是谁呢?
 *             this(一个类本身对象就是this)
 *
 * C:静态方法及锁对象问题?
 *         静态方法的锁对象是谁呢?
 *             类的字节码文件对象。(反射会讲)
 */
public class SellTicketDemo {
    public static void main(String[] args) {
        // 创建资源对象
        SellTicket st = new SellTicket();

        // 创建三个线程对象
        Thread t1 = new Thread(st, "窗口1");
        Thread t2 = new Thread(st, "窗口2");
        Thread t3 = new Thread(st, "窗口3");

        // 启动线程
        t1.start();
        t2.start();
        t3.start();
    }
}

package cn.itcast_11;



/**
*      本模块利用了同步代码块操作相同代码时,不管执行的位置在哪里,都会一样的效果,利用X%2==0的特点,将线程的路径分为两边,但前面说过,同步代码块操作相同代码时是不需要考虑位置,因为他们的锁是相同的特性,由此引出静态同步方法,与非静态同步方法。因为if与else内的效果是一样的,若效果不一样,说明两段代码锁的内容不一致,只要改成锁是相同的,就能达到效果一样从而说明同步方法,与静态同步方法需要哪种锁。
*/

/**
*     同步代码块:任意对象,但对象定义不能在代码块的括号内进行,不然每次都创建新对象维护锁,锁的意义失效
*     同步方法:本类内部对象:this,这个条件是隐含的。
*     静态同步方法:本类的.class 类对象,因为静态在类初始化前已经执行,所以普通的对象没用办法作为锁,因为static已经在它创建前创建好了,比static更早创建的类,只有类加载到方法区的Class类
*/
public class SellTicket implements Runnable {

    // 定义100张票
    private static int tickets = 100;

    // 定义同一把锁
    private Object obj = new Object();
    private Demo d = new Demo();

    private int x = 0;
    
    //同步代码块用obj做锁
//    @Override
//    public void run() {
//        while (true) {
//            synchronized (obj) {
//                if (tickets > 0) {
//                    try {
//                        Thread.sleep(100);
//                    } catch (InterruptedException e) {
//                        e.printStackTrace();
//                    }
//                    System.out.println(Thread.currentThread().getName()
//                            + "正在出售第" + (tickets--) + "张票 ");
//                }
//            }
//        }
//    }
    
    //同步代码块用任意对象做锁
//    @Override
//    public void run() {
//        while (true) {
//            synchronized (d) {
//                if (tickets > 0) {
//                    try {
//                        Thread.sleep(100);
//                    } catch (InterruptedException e) {
//                        e.printStackTrace();
//                    }
//                    System.out.println(Thread.currentThread().getName()
//                            + "正在出售第" + (tickets--) + "张票 ");
//                }
//            }
//        }
//    }
    
    @Override
    public void run() {
        while (true) {
            if(x%2==0){
                synchronized (SellTicket.class) {
                    if (tickets > 0) {
                        try {
                            Thread.sleep(100);
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                        System.out.println(Thread.currentThread().getName()
                                + "正在出售第" + (tickets--) + "张票 ");
                    }
                }
            }else {
//                synchronized (d) {
//                    if (tickets > 0) {
//                        try {
//                            Thread.sleep(100);
//                        } catch (InterruptedException e) {
//                            e.printStackTrace();
//                        }
//                        System.out.println(Thread.currentThread().getName()
//                                + "正在出售第" + (tickets--) + "张票 ");
//                    }
//                }
                
                sellTicket();
                
            }
            x++;
        }
    }
//   表明任意类型都可以
//    private void sellTicket() {
//        synchronized (d) {
//            if (tickets > 0) {
//            try {
//                    Thread.sleep(100);
//            } catch (InterruptedException e) {
//                    e.printStackTrace();
//            }
//            System.out.println(Thread.currentThread().getName()
//                        + "正在出售第" + (tickets--) + "张票 ");
//            }
//        }
//    }
    
    //如果一个方法一进去就看到了代码被同步了,那么我就再想能不能把这个同步加在方法上呢?
//     private synchronized void sellTicket() {
//            if (tickets > 0) {
//            try {
//                    Thread.sleep(100);
//            } catch (InterruptedException e) {
//                    e.printStackTrace();
//            }
//            System.out.println(Thread.currentThread().getName()
//                        + "正在出售第" + (tickets--) + "张票 ");
//            }
//    }
    
    private static synchronized void sellTicket() {
        if (tickets > 0) {
        try {
                Thread.sleep(100);
        } catch (InterruptedException e) {
                e.printStackTrace();
        }
        System.out.println(Thread.currentThread().getName()
                    + "正在出售第" + (tickets--) + "张票 ");
        }
}
}

class Demo {
}

原文地址:https://www.cnblogs.com/canceler/p/4634983.html