Synchronized

定义
  • Java中的关键字,是一种重量级同步锁
修饰的对象
   修饰对象                 作用对象


   方法块                   调用该代码块的对象     synchronized(this) {}


   修饰方法                 调用该方法的对象


   静态方法                 这个类的所有对象


   类                      这个类的所有对象
特点
  • Synchronized 不能被继承
  • 每个对象只有一个锁(lock)与之相关联,谁拿到这个锁谁就可以运行它所控制的那段代码
  • 现同步是要很大的系统开销作为代价的,甚至可能造成死锁,所以尽量避免无谓的同步控制
  • (synchorized)锁分为对象锁(同步方法/同步代码块)和类锁(同步类/同步静态方法),两者之间互不干扰
  • 一个对象只有一个锁
  • 不同对象的对象锁是互不干扰的,但每一个类只有一个类锁
修饰方法快
  • 用于修饰方法块,作用于该代码块的对象,在多线程情况下,当该对象在一个线程中被调用时,被锁住的内容只能由该线程执行,其他线程都处于等待状态,知道该线程执行完毕锁住内容,但是当该方法由非锁住的代码块时,其他线程是可以访问该方法的非锁住内容的

      public class Counter implements Runnable{
          private int count;
      
          public Counter() {
              count = 0;
          }
      
          public void countAdd() {
              synchronized(this) {
                  for (int i = 0; i < 5; i ++) {
                      try {
                          Log.e("mj",Thread.currentThread().getName() + ":" + (count++));
                          Thread.sleep(100);
                      } catch (InterruptedException e) {
                          e.printStackTrace();
                      }
                  }
              }
          }
      
          //非synchronized代码块,未对count进行读写操作,所以可以不用synchronized
          public void printCount() {
              for (int i = 0; i < 5; i ++) {
                  try {
      
                      Log.e("mj",Thread.currentThread().getName() + " count:" + count);
                      Thread.sleep(100);
                  } catch (InterruptedException e) {
                      e.printStackTrace();
                  }
              }
          }
      
          @Override
          public void run() {
              String threadName = Thread.currentThread().getName();
              if (threadName.equals("A")) {
                  countAdd();
              } else if (threadName.equals("B")) {
                  printCount();
              }
          }
      }
    

    //调用
    Counter counter = new Counter();
    Thread thread1 = new Thread(counter, “A”);
    Thread thread2 = new Thread(counter, “B”);
    thread1.start();
    thread2.start();

修饰方法
  • 用于修饰方法,作用于该代码块的对象,在多线程情况下,当该对象在一个线程中被调用时,被锁住的内容只能由该线程执行,其他线程都处于等待状态

    public class MyThread implements Runnable{
    private static int count;

      public MyThread() {
          count = 0;
      }
    
      @Override
      public synchronized void run() {
              for (int i = 0; i < 5; i++) {
                  try {
                     Log.e("mj",Thread.currentThread().getName() + ":" + (count++));
                      Thread.sleep(100);
                  } catch (InterruptedException e) {
                      e.printStackTrace();
                  }
              }
          }
    
    
      public int getCount() {
          return count;
      }
    

    }

    //调用
    MyThread syncThread = new MyThread();
    Thread thread1 = new Thread(syncThread, “SyncThread1”);
    Thread thread2 = new Thread(syncThread, “SyncThread2”);
    thread1.start();
    thread2.start();

修饰静态方法
  • 用于修饰静态方法,作用于该类的所有对象,在多线程情况下,无论线程持有该类的那个对象,在同一时刻只有一个线程可以访问,其他线程无论是否是有同一对象,都必须处于等待状态

    public class MyThread   implements  Runnable{
        private static int count;
    
        public MyThread() {
            count = 0;
        }
    
        @Override
        public void run() {
              method();
            }
    
        public synchronized static void method() {
            for (int i = 0; i < 5; i ++) {
                try {
                    Log.e("mj",Thread.currentThread().getName() + ":" + (count++));
                    Thread.sleep(100);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    
    }
    
    
      //调用
       Thread thread1 = new Thread( new MyThread(), "SyncThread1");
        Thread thread2 = new Thread( new MyThread(), "SyncThread2");
        thread1.start();
        thread2.start();
    
修饰一个类
  • 用于修饰静态方法,作用于该类的所有对象,在多线程情况下,无论线程持有该类的那个对象,在同一时刻只有一个线程可以访问,其他线程无论是否是有同一对象,都必须处于等待状态

     public class MyThread implements Runnable {
        private static int count;
    
        public MyThread() {
            count = 0;
        }
    
        @Override
        public void run() {
            method();
        }
    
        public static void method() {
            synchronized (MyThread.class) {
                for (int i = 0; i < 5; i++) {
                    try {
                        System.out.println(Thread.currentThread().getName() + ":" + (count++));
                        Thread.sleep(100);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }
        }
    
        }
    
    	//调用
    	       Thread thread1 = new Thread( new MyThread(), "SyncThread1");
    		        Thread thread2 = new Thread( new MyThread(), "SyncThread2");
    		        thread1.start();
    	        thread2.start();
    
死锁
  • 造成的原因

    • 线程1/2/3分别持有A/B/C对象,现在线程1想获取B对象,线程2想获取C对象,线程3想获取A对象,但是三个对象分别被三个线程持有,随意导致三个线程不能释放也不能获取,从而导致死锁
  • 解决方案

    • 减小了锁定的范围

    • 调整申请锁的顺序

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值