java synchronized

一、简介

常用的有如下几种方式

synchronized(this)、synchronized(Object)与synchronized修饰静态方法、synchronized(class)

二、修饰本身对象

如下两种写法是具有一样的效果,都是锁住自己本身的对象,当同一对象多次调用时,同步锁会起作用。

1.synchronized代码块

写法一:

public synchronized void method()
{
   // todo
}

写法二:

public void method()
{
   synchronized(this) {
      // todo
   }
}

2.非synchronized代码块

class Counter implements Runnable{
   private int count;

   public Counter() {
      count = 0;
   }

   public void countAdd() {
      synchronized(this) {
         for (int i = 0; i < 5; i ++) {
            try {
               System.out.println(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 {
            System.out.println(Thread.currentThread().getName() + " count:" + count);
            Thread.sleep(100);
         } catch (InterruptedException e) {
            e.printStackTrace();
         }
      }
   }

   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();

结果

A:0
B count:1
A:1
B count:2
A:2
B count:3
A:3
B count:4
A:4
B count:5

上面代码中countAdd是一个synchronized的,printCount是非synchronized的。从上面的结果中可以看出一个线程访问一个对象的synchronized代码块时,别的线程可以访问该对象的非synchronized代码块而不受阻塞。

三、同步一段代码

当没有明确的对象作为锁,只是想让一段代码同步时,可以创建一个特殊的对象来充当锁:

class Test implements Runnable
{
   private byte[] lock = new byte[0];  // 特殊的instance变量
   public void method()
   {
      synchronized(lock) {
         // todo 同步代码块
      }
   }

   public void run() {

   }
}

四、修饰类

如果synchronized作用的对象是一个静态方法或一个类,则它取得的锁是对类,该类所有的对象同一把锁,那也就是说对任何对象都是同步的。

1.修饰类

class ClassName {
   public void method() {
      synchronized(ClassName.class) {
         // todo
      }
   }
}

2.修饰静态方法

class SyncThread implements Runnable {
   public synchronized static void method() {
      //todo
   }
}        

参考:https://blog.csdn.net/luoweifu/article/details/46613015 

原文地址:https://www.cnblogs.com/AntonioSu/p/14389850.html