线程八锁(非静态同步方法与静态同步方法的区别)

所为线程八锁是指在工作中锁的几种情况,网上搜了好多,发现列举的八个代码实例,有不少代码实例都可有可无的,但是呢,为了完整地记录下这次的学习,那我写也写全吧,手动苦笑~~,请看列子

1.同一个对象,开启两个线程,分别调用两个非静态同步方法

package com.cjian.thread8lock;

/**
 * Created by cjian on 2020/8/20.
 * 两个线程调同一个对象的两个同步方法
 *
 * 原因分析:锁的对象是方法的调用者,即t8l,所以两个方法用的是同一个锁,因此先调用的先执行
 */
public class Lock1 {

    public static void main(String[] args) {
        Test8Lock1 t8l = new Test8Lock1();

        new Thread(new Runnable() {
            @Override
            public void run() {
                t8l.getOne();
            }
        }).start();

        new Thread(new Runnable() {
            @Override
            public void run() {
                t8l.getTwo();
            }
        }).start();
    }

}
class Test8Lock1{
    public synchronized  void getOne(){
        System.out.println("-->one");
    }

    public synchronized  void getTwo(){
        System.out.println("-->two");
    }
}

输出:

总结:被synchronized修饰的非静态方法,锁的是调用者本身

2.在1的基础上,给getOne增加了休眠期(其实就是为了再次验证1的结论)

package com.cjian.thread8lock;

/**
 * Created by cjian on 2020/8/20.
 * 锁的同一个对象,先持有锁的先执行
 */
public class Lock2 {

    public static void main(String[] args) {
        Test8Lock2 t8l = new Test8Lock2();

        new Thread(new Runnable() {
            @Override
            public void run() {
                t8l.getOne();
            }
        }).start();

        new Thread(new Runnable() {
            @Override
            public void run() {
                t8l.getTwo();
            }
        }).start();
    }

}
class Test8Lock2{
    public synchronized  void getOne(){
        try {
            System.out.println("-->sleep 1s");
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("-->one");
    }

    public synchronized  void getTwo(){
        System.out.println("-->two");
    }
}

输出:

3.同一个对象调用非静态同步方法与普通方法

package com.cjian.thread8lock;

/**
 * Created by cjian on 2020/8/20.
 * 同一个对象调用同步方法与普通方法
 * <p>
 * 原因分析:普通方法不受锁的影响
 */
public class Lock3 {

    public static void main(String[] args) {
        Test8Lock3 t8l = new Test8Lock3();

        new Thread(new Runnable() {
            @Override
            public void run() {
                t8l.getOne();
            }
        }).start();

        new Thread(new Runnable() {
            @Override
            public void run() {
                t8l.getTwo();
            }
        }).start();

        new Thread(new Runnable() {
            @Override
            public void run() {
                t8l.getThree();
            }
        }).start();
    }

}

class Test8Lock3 {
    public synchronized void getOne() {
        try {
            System.out.println("-->sleep 1s");
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("-->one");
    }

    public synchronized void getTwo() {
        System.out.println("-->two");
    }

    public void getThree() {
        System.out.println("-->three");
    }
}

输出:

总结:普通方法不受锁影响

4.两个不同的对象分别调用非静态同步方法

package com.cjian.thread8lock;

/**
 * Created by cjian on 2020/8/20.
 * 两个线程分表调用两个对象的同步方法
 * <p>
 * 原因分析:锁的对象不同,各自执行各自的
 */
public class Lock4 {

    public static void main(String[] args) {

        Test8Lock3 t8l1 = new Test8Lock3();
        Test8Lock3 t8l2 = new Test8Lock3();
        new Thread(new Runnable() {
            @Override
            public void run() {
                t8l1.getOne();
            }
        }).start();

        new Thread(new Runnable() {
            @Override
            public void run() {
                t8l2.getTwo();
            }
        }).start();


    }

}

class Test8Lock4 {
    public synchronized void getOne() {
        try {
            System.out.println("-->sleep 1s");
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("-->one");
    }

    public synchronized void getTwo() {
        System.out.println("-->two");
    }

}

输出:


 总结:通过1我们知道,非静态同步方法锁的是调用者本身,而本列中,锁得是不同的对象,因此two先输出,再次验证1的结论~_~

5.同一个对象分别调用静态同步方法和非静态同步方法

package com.cjian.thread8lock;

/**
 * Created by cjian on 2020/8/20.
 *
 * <p>
 * 原因分析:static 修饰的同步方法锁的是class,单synchronized锁的是调用者本身
 */
public class Lock5 {

    public static void main(String[] args) {
        Test8Lock5 t8l = new Test8Lock5();

        new Thread(new Runnable() {
            @Override
            public void run() {
                t8l.getOne();
            }
        }).start();

        new Thread(new Runnable() {
            @Override
            public void run() {
                t8l.getTwo();
            }
        }).start();

    }

}

class Test8Lock5 {
    public static synchronized void getOne() {
        try {
            System.out.println("-->sleep 1s");
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("-->one");
    }

    public synchronized void getTwo() {
        System.out.println("-->two");
    }

}

输出:

总结:咦~,这不是用一个对象的调用吗,怎么会这样呢,哈哈,这里又是另一个重要的结论:静态同步方法锁的是class,再结合1的结论(非静态同步方法锁的是调用者本身,即t8l),因此,本列中实际上是锁的不同对象,一个是实例对象t8l,一个是class(或者应该说是不同的锁)

6.同一个对象分别调用两个静态同步方法

package com.cjian.thread8lock;

/**
 * Created by cjian on 2020/8/20.
 *
 * <p>
 * 原因分析:static 修饰的同步方法锁的是class,
 */
public class Lock6 {

    public static void main(String[] args) {
        Test8Lock6 t8l = new Test8Lock6();

        new Thread(new Runnable() {
            @Override
            public void run() {
                t8l.getOne();
            }
        }).start();

        new Thread(new Runnable() {
            @Override
            public void run() {
                t8l.getTwo();
            }
        }).start();

    }

}

class Test8Lock6 {
    public static synchronized void getOne() {
        try {
            System.out.println("-->sleep 1s");
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("-->one");
    }

    public static synchronized void getTwo() {
        System.out.println("-->two");
    }

}

输出:

进一步验证5的结论

7.两个不同的对象分别调用静态同步方法和非静态同步方法

package com.cjian.thread8lock;

/**
 * Created by cjian on 2020/8/20.
 *
 * <p>
 * 原因分析:static 修饰的同步方法锁的是class,
 */
public class Lock7 {

    public static void main(String[] args) {
        Test8Lock7 t8l1 = new Test8Lock7();
        Test8Lock7 t8l2 = new Test8Lock7();

        new Thread(new Runnable() {
            @Override
            public void run() {
                t8l1.getOne();
            }
        }).start();

        new Thread(new Runnable() {
            @Override
            public void run() {
                t8l2.getTwo();
            }
        }).start();

    }

}

class Test8Lock7 {
    public static synchronized void getOne() {
        try {
            System.out.println("-->sleep 1s");
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("-->one");
    }

    public  synchronized void getTwo() {
        System.out.println("-->two");
    }

}

输出:

可充分验证5的结论

8.两个不同的对象分别调用两个静态同步方法

 

package com.cjian.thread8lock;

/**
 * Created by cjian on 2020/8/20.
 *
 * <p>
 * 原因分析:static 修饰的同步方法锁的是class,
 */
public class Lock8 {

    public static void main(String[] args) {
        Test8Lock8 t8l1 = new Test8Lock8();
        Test8Lock8 t8l2 = new Test8Lock8();

        new Thread(new Runnable() {
            @Override
            public void run() {
                t8l1.getOne();
            }
        }).start();

        new Thread(new Runnable() {
            @Override
            public void run() {
                t8l2.getTwo();
            }
        }).start();

    }

}

class Test8Lock8 {
    public static synchronized void getOne() {
        try {
            System.out.println("-->sleep 1s");
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("-->one");
    }

    public static synchronized void getTwo() {
        System.out.println("-->two");
    }

}

输出:

再次充分验证静态同步方法锁的是class

 

总结:非静态同步方法锁的是调用者对象本身,静态同步方法锁的是class 

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值