Toc
  1. synchronized 关键字
  2. 知识点
0 results found
liang
多线程笔记
2019/07/25 Java 多线程
synchronized 关键字

对某个对象加锁

public class T{
  private int count = 10;
  public void m(){
    synchronized (this){
          count--;
          System.out.println(Thread.currentThread().getName() + "count = " + count);
    }
  }
}

等同于

public class T{
  private int count = 10;
  public synchronized void m(){
      count--;
      System.out.println(Thread.currentThread().getName() + "count = " + count);

  }
}
知识点
  1. 同步方法和非同步方法可以同时调用
  2. 写方法加锁,读方法不加锁,会产生脏读问题
  3. 一个同步方法可以调用另一个同步方法,一个线程已经拥有某个对象的锁,再次申请的时候仍然会得到该对象的锁,也就是说synchronized获得的锁是可重入的(子类调用父类的同步方法也是可以的)
public class T{

  synchronized void m(){
    System.out.println("m start")
    System.out.println("m end")
  }

  public static void main(String[] args) {
    new TT().m();
  }

}

class TT extends T{

  synchronized void m(){
    System.out.println("child start")
    super.m();
    System.out.println("child end")
  }
}
  1. 程序在执行过程中,如果出现异常,默认情况锁会被释放,如果不想释放需要处理异常
  2. volatile 关键字 使一个变量在多个线程间可见
    A B线程都用到一个变量,java默认是A线程缓冲区中保留一份copy,这样如果B线程修改了该变量,则A线程未必知道
    在下面的代码中,running是存在于堆内存的t对象中,当线程t1开始运行的时候,running值从内存中读到t1线程的工作区,在运行过程中直接使用这个copy,并不会每次都去读取堆内存,这样当主线程修改running 的值后,t1线程感知不到,所以不会停止运行
    public class T{
    
      volatile boolean running = true;
      void m(){
        System.out.println("start");
        while(running){
    
        }
        System.out.println("end");
      }
    
      public static void main(String[] args) {
        T t = new T();
    
        new Thread(t::m,"t1").start();
    
        try {
          TimeUnit.SECONDS.sleep(1);
        } catch(Exception e) {
          e.printStackTrace();
        }
    
        t.running = false;
      }
    
    }
打赏
支付宝
微信
本文作者:liang
版权声明:本文首发于liang的博客,转载请注明出处!