• synchronized类锁,方法锁,块级锁,一文看懂


    先说结论:

    1.synchronized加到静态方法上 调用静态方法时会锁住此类,如果此类有2个静态方法都加上了synchronized则同一时刻只能有一个静态方法被调用

    2.synchronized加到普通方法上 该类的实例(实例指new出来的对象)同一时刻只能调用一个方法,如果多个线程同时调用该实例的多个synchronized方法则只有一个线程会调用到,其他线程会阻塞等待获取锁

    3.synchronized(obj)放到方法里面作为代码块锁时则要看锁住的对象是什么:

    3.1如果2个方法里面的代码块锁锁住的对象是同一个则多个线程调用这2个方法时只有一个线程会调用到,其他线程会阻塞等待,类似于2中的方法锁
    3.2如果2个方法里面的代码块锁住的是2个不同的对象则同一时刻允许2个线程同时调用这2个方法,参考下面代码中Demo类里面的test4和test5

    代码如下:

    
    public class Main {
        public static void main(String[] args) {
            //java.util.concurrent.CopyOnWriteArrayList
            Demo demo = new Demo();
            Thread t1 = new Thread(new Runnable() {
                @Override
                public void run() {
                    demo.test3();
                    Demo.test5();
                }
            });
            Thread t2 = new Thread(new Runnable() {
                @Override
                public void run() {
                    demo.test4();
                    Demo.test6();
                }
            });
    
            Thread t3 = new Thread(new Runnable() {
                @Override
                public void run() {
                    Demo.test5();
                }
            });
            Thread t4 = new Thread(new Runnable() {
                @Override
                public void run() {
                    Demo.test6();
                }
            });
    
            t1.start();
            t2.start();
            t3.start();
            t4.start();
    
        }
    }
    
    
    
    class Demo{
    
        private Object obj1 = new Object();
        private Object obj2 = new Object();
    
        public synchronized void test1(){
            try {
                System.out.println("test1开始执行------"+Thread.currentThread().getName());
                Thread.sleep(2000);
                System.out.println("test1结束执行------"+Thread.currentThread().getName());
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        public synchronized void test2(){
            try {
                System.out.println("test2开始执行------"+Thread.currentThread().getName());
                Thread.sleep(2000);
                System.out.println("test2结束执行------"+Thread.currentThread().getName());
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    
        public void test3(){
            synchronized (obj1){
                try {
                    System.out.println("test3开始执行------"+Thread.currentThread().getName());
                    Thread.sleep(2000);
                    System.out.println("test3结束执行------"+Thread.currentThread().getName());
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    
        public void test4(){
            synchronized (obj2){
                try {
                    System.out.println("test4开始执行------"+Thread.currentThread().getName());
                    Thread.sleep(2000);
                    System.out.println("test4结束执行------"+Thread.currentThread().getName());
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    
        public synchronized static void test5(){
            try {
                System.out.println("test5开始执行------"+Thread.currentThread().getName());
                Thread.sleep(2000);
                System.out.println("test5结束执行------"+Thread.currentThread().getName());
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    
        public synchronized static void test6(){
            try {
                System.out.println("test6开始执行------"+Thread.currentThread().getName());
                Thread.sleep(2000);
                System.out.println("test6结束执行------"+Thread.currentThread().getName());
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    
    }
    
    
  • 相关阅读:
    MVC 导出Execl 的总结几种方式 (一)
    MVC 中导出Execl 对 科学计数 的转化
    MVC 中使用kindEditor 图片上传在IE 上进行上传出现的问题
    C# 后台处理图片的几种方式
    MVC 手机端页面 使用标签file 图片上传到后台处理
    MVC 中使用log4net 打印重复日志解决方法
    MVC 初始 Log4net (一)
    MVC 局部加载页面的实例
    K8S从入门到放弃系列-(16)Kubernetes集群Prometheus-operator监控部署
    K8S从入门到放弃系列-(15)Kubernetes集群Ingress部署
  • 原文地址:https://www.cnblogs.com/bcde/p/13527403.html
Copyright © 2020-2023  润新知