zoukankan      html  css  js  c++  java
  • 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 

  • 相关阅读:
    标签的讲解
    属性分类
    LeetCode 003. 无重复字符的最长子串 双指针
    Leetcode 136. 只出现一次的数字 异或性质
    Leetcode 231. 2的幂 数学
    LeetCode 21. 合并两个有序链表
    象棋博弈资源
    acwing 343. 排序 topsort floyd 传播闭包
    Leetcode 945 使数组唯一的最小增量 贪心
    Leetcode 785 判断二分图 BFS 二分染色
  • 原文地址:https://www.cnblogs.com/AntonioSu/p/14389850.html
Copyright © 2011-2022 走看看