java中多线程同步函数this锁的证明以及静态同步函数的锁

//首先是对多线程this锁的证明,这里是看大牛博客的然后自己理解了的学习笔记,这里模拟两个窗口进行车票的售卖,当两个窗口对同一资源车票在竞争过程中产生的同步问题,因此通过加锁解决数据安全问题,代码中若将sale1中的synchronized中的this锁换为obj也就是再类中的域定义的锁的时候会出现数据安全问题。

//如何证明:对于两个线程,同时启动,一个线程使用同步函数,另一个使用同步代码块儿,此时对同步代码块儿中的锁进行替换为自己定义的,若此时有数据安全问题那么说明同步代码块儿和同步函数所使用的锁不一样,若将同步代码块儿中的锁更换为this锁,此时没有数据安全问题,那么说明同步代码块儿和同步函数所使用的琐事同一个锁。

package Thread01;

class Thread02 implements Runnable{

    private static int countTicket = 100;
    private static Object obj = new Object();
    public static boolean flag = true;
    @Override
    public void run() {

        if(flag){//使用同步锁--this
            while(countTicket>0){
                try {
                    Thread.sleep(50);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                sale1();
            }
        }else{//使用同步函数
            while(countTicket>0){
                try {
                    Thread.sleep(50);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                sale();
            }
        }

    }

    public void sale1(){

        synchronized(this){
            if(countTicket>0){ //------当把这个if判断去掉 最后还是会有两个线程来争夺最后一张票 会挨个执行,数据不会出错,但是逻辑会出错。
            System.out.println("当前线程名字:"+Thread.currentThread().getName()+";出售第"+(100 - countTicket + 1)+"张票。");
            countTicket--;
         }
        }
    }

    public synchronized void sale(){

        if(countTicket>0){
            //卖票
            System.out.println("当前线程名字:"+Thread.currentThread().getName()+";出售第"+(100 - countTicket + 1)+"张票。");
            countTicket--;
        }

    }
}

public class ThreadDemo {

    public static void main(String[] args) throws InterruptedException {
        Thread02 t = new Thread02();

        Thread t1 = new Thread(t,"窗口1");
        Thread t2 = new Thread(t,"窗口2");
        t1.start();
        Thread.sleep(50);
        Thread02.flag=false;
        t2.start();
    }

}

//下面是对静态同步函数的锁的证明,他是一个字节码class,我们同样通过代码块儿和一个静态同步函数来看,我们将同步函数中的锁更换为.class的字节码时没有数据安全问题,那么说明此事静态同步函数的锁为字节码。见代码:

package Thread01;

class Thread02 implements Runnable{

    private static int countTicket = 100;
    private static Object obj = new Object();
    public static boolean flag = true;
    @Override
    public void run() {

        if(flag){//使用同步锁--this
            while(countTicket>0){
                try {
                    Thread.sleep(50);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                sale1();
            }
        }else{//使用同步函数
            while(countTicket>0){
                try {
                    Thread.sleep(50);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                sale();
            }
        }

    }

    public void sale1(){

        synchronized(Thread02.class){
            if(countTicket>0){ //------当把这个if判断去掉 最后还是会有两个线程来争夺最后一张票 会挨个执行,数据不会出错,但是逻辑会出错。
            System.out.println("当前线程名字:"+Thread.currentThread().getName()+";出售第"+(100 - countTicket + 1)+"张票。");
            countTicket--;
         }
        }
    }

    public static synchronized void sale(){

        if(countTicket>0){
            //卖票
            System.out.println("当前线程名字:"+Thread.currentThread().getName()+";出售第"+(100 - countTicket + 1)+"张票。");
            countTicket--;
        }

    }
}

public class ThreadDemo {

    public static void main(String[] args) throws InterruptedException {
        Thread02 t = new Thread02();

        Thread t1 = new Thread(t,"窗口1");
        Thread t2 = new Thread(t,"窗口2");
        t1.start();
        Thread.sleep(50);
        Thread02.flag=false;
        t2.start();
    }

}

猜你喜欢

转载自blog.csdn.net/small__snail__5/article/details/81269543