唐僧喜欢小龙女

导航

线程八锁学习

1、锁的东西就三个

对象和Class和自己定义的Object

2、锁的具体使用

这里用同步方法举例的

2.1 同一个类里面两个普通的 synchronized 方法

/**
 *
 * 这个类中的两个方法用的都是同一个锁
 *
 */
public class WindowSell5 {


    public synchronized void sendMsg() throws InterruptedException{

            TimeUnit.SECONDS.sleep(4);
            System.out.println("sendMsg");
    }

    public synchronized void call(){
            System.out.println("打电话");
    }




}








/**
 *
 *  两个线程两个方法,先打印那个 先打印sendmsg 然后打印打电话。
 *  windowSell5 中的两个方法用的是同一个锁,锁是对象
 *  两个锁谁先拿到谁执行。所以a线程先执行,即使说sendMsg 执行比较耗时,b线程也不会执行
 *  a线程和b线程用的是同一个锁,你用了我就不能用了,只有你释放了我才能拿到锁。所以说b线程一直会等待
 *
 */
public class WindowSell5Test {
    public static void main(String[] args) throws InterruptedException{
        WindowSell5 windowSell5 = new WindowSell5();

        new Thread(()->{
            try {
                windowSell5.sendMsg();
            }catch (Exception e){

            }
        },"a").start();

        //如果这里不sleep 下 线程b也可能执行
        TimeUnit.SECONDS.sleep(1);

        new Thread(()->{
            windowSell5.call();
        },"b").start();



    }
}

  



2.2同一个类里面一个synchronized 方法、一个普通的方法

 

/**
 *
 * 这个类中的一个方法有锁一个没有锁
 *
 */
public class WindowSell1 {


    public synchronized void sendMsg() throws InterruptedException{

        TimeUnit.SECONDS.sleep(4);
        System.out.println("sendMsg");

    }


    public void hello(){
        System.out.println("hello");
    }
}




/**
 * 两个线程两个方法,先打印那个 打电话
 *
 * a 线程执行后比较耗时4s,同时有把锁,锁  是  方法的调用者就是windowSell1 这个对象
 * 而线程b 没有锁,不存在锁的争抢,b 线程一看,你忙着呢,我就不等你了我就执行了。
 *
 *
 *
 *
 *
 *
 */
public class WindowSell1Test {
    public static void main(String[] args) throws Exception{

        WindowSell1 windowSell1 = new WindowSell1();


        new Thread(()->{
            try {
                windowSell1.sendMsg();
            }catch (Exception e){

            }
        },"a").start();


        TimeUnit.SECONDS.sleep(1);

        new Thread(()->{
            windowSell1.hello();

        },"b").start();


    }
}

  

2.3 同一个类里面两个用static 修饰的 synchronized 方法

public class WindowSell3 {

    public static synchronized void sendMsg() throws InterruptedException{

        TimeUnit.SECONDS.sleep(4);
        System.out.println("sendMsg");
    }

    public static synchronized void call(){
        System.out.println("打电话");
    }
}


/**
 *
 *  WindowSell3 中的两个方法 sendMsg call 都有锁,有一个共同的锁,锁是WindowSell3
 *  所以线程a 执行的时候,线程b需要等待
 *
 *  即使说new 两个对象 一个执行 sendMsg 一个执行call 也是线程先打印 sendmsg 然后打印 打电话
 *
 *
 *
 */
public class WindowSell3Test {
    public static void main(String[] args) throws InterruptedException{

        WindowSell3 windowSell3 = new WindowSell3();
        WindowSell3 windowSell3_1 = new WindowSell3();

        new Thread(()->{
            try {
                windowSell3.sendMsg();
            }catch (InterruptedException i){

            }

        },"a").start();




        TimeUnit.SECONDS.sleep(1);
        new Thread(()->{
            //windowSell3.call();
            windowSell3_1.call();

        },"b").start();

    }
}

 

2.4 同一个类里面一个用static 修饰的 synchronized 方法,一个不用static 修饰的 synchronized 方法 

public class WindowSell4 {

    public static synchronized void sendMsg() throws InterruptedException{

        TimeUnit.SECONDS.sleep(4);
        System.out.println("sendMsg");
    }

    public synchronized void call(){
        System.out.println("打电话");
    }

}


/**
 *
 *
 * 两个线程两个方法,先打印那个 b线程
 * WindowSell4 中的两个方法 sendMsg call 都有锁,sendMsg 这个方法的锁是类WindowSell4
 * 而call 这个方法的锁是 对象,两个方法两把锁。
 * 所以说 先打印 打电话
 *
 */
public class WindowSell4Test {
    public static void main(String[] args) throws InterruptedException{
        WindowSell4 windowSell4 = new WindowSell4();


        new Thread(()->{
            try {
                windowSell4.sendMsg();
            }catch (Exception e){

            }
        },"a").start();

        //如果这里不sleep 下 线程b也可能执行
        TimeUnit.SECONDS.sleep(1);

        new Thread(()->{
            windowSell4.call();
        },"b").start();




    }
}

  

3、同步代码块的使用

public class WindowSell5 {


    public  void sendMsg(){

        synchronized (WindowSell5.class){
            try {
                TimeUnit.SECONDS.sleep(3);

            }catch (InterruptedException e){

            }
            System.out.println("sendMsg");
        }


    }

    public  void call(){
        synchronized (this){
            try {
                TimeUnit.SECONDS.sleep(2);

            }catch (InterruptedException e){

            }
            System.out.println("打电话");

        }
    }

    public  void hello(){
        String s = "hello";
        synchronized (s){
            System.out.println("hello");

        }
    }
}


public class MainTest1 {
    public static void main(String[] args) {
        WindowSell5 windowSell5 = new WindowSell5();

        /**
         *  
         *  1、hello 先执行,其次是call,其次是sendMsg
         *  2、三个不同的锁
         */
        new Thread(()->{
            windowSell5.sendMsg();
        },"a").start();

        new Thread(()->{
            windowSell5.call();
        },"b").start();
        new Thread(()->{
            windowSell5.hello();
        },"c").start();
    }
}

 

 

 

 

 

 

posted on 2021-05-16 19:31  与时具进&不忘初心  阅读(84)  评论(0编辑  收藏  举报