java多线程学习笔记(六)

本节开始synchronized关键字的最后一部分内容:

静态同步方法synchronized方法与synchronized(class)代码块

关键字synchronized还可以用在static静态方法上,如果这样写,相当于对当前的*.java文件对应的Class类进行持锁。

结论写在前面:synchronized加到静态方法上和加到非静态方法上表面上的使用效果是一样的,但本质效果不同,synchronized关键字加到static静态方法上是给Class类加锁,而synchronized关键字加到非静态方法上是给对象加锁,两者不是同一个锁,所以同时使用的时候,当两个线程分表调用两种方法时,会出现异步的效果;

同步synchronized(class)代码块的作用其实是和synchronized static方法的作用是一样的

同步方法容易造成死循环,有案例如下:

 

public class Service {

  synchronized  public void methodA(){
      System.out.println("methodA begin");
      boolean isContinueRun = true;
      while (isContinueRun) {

      }
      System.out.println("methodA end");
  }

  synchronized  public void methodB(){
      System.out.println("methodB begin");
      System.out.println("methodB end");
  }

}

public class ThreadA extends  Thread{
    private Service service;

    public ThreadA(Service service) {
        this.service = service;
    }

    @Override
    public void run() {
        super.run();
        service.methodA();
    }
}


public class ThreadB extends  Thread{


    private Service service;

    public ThreadB(Service service) {
        this.service = service;
    }

    @Override
    public void run() {
        super.run();
        service.methodB();
    }
}


public class Test {
    public static void main(String[] args) {
        Service service = new Service();
        ThreadA threadA = new ThreadA(service);
        threadA.setName("a");
        threadA.start();
        ThreadB threadB = new ThreadB(service);
        threadB.setName("b");
        threadB.start();

    }
}

 

直接使用对象锁,会导致线程无限等待,但是如果使用synchronized代码块的话,有如下的改进:

public class Service {

    Object object1 = new Object();
    public void methodA(){
        synchronized (object1) {
            System.out.println("methodA begin");
            boolean isContinueRun = true;
            while (isContinueRun) {

            }
            System.out.println("methodA end");
        }

  }
    Object object2 = new Object();
    public void methodB(){
        synchronized (object2) {
            System.out.println("methodB begin");
            System.out.println("methodB end");
        }

  }


}

这样的话就不会出现同步等待的状况,因为 methodA 和 methodB 是可以异步调用的。

内置类与静态内置类

我们首先看看内置类和静态内枝类的区别,其实我们光从这个名字还不太容易高明白,下面是截取的网上的,理解起来还容易一点。

从字面上看,一个被称为静态嵌套类,一个被称为内部类。从字面的角度解释是这样的:什么是嵌套?嵌套就是我跟你没关系,自己可以完全独立存在,但是我就想借你的壳用一下,来隐藏一下我自己。什么是内部?内部就是我是你的一部分,我了解你,我知道你的全部,没有你就没有我。(所以内部类对象是以外部类对象存在为前提的)

public class Test190 {
    class  inner{
        public void show() {
            System.out.println("这是内部类");
        }
    }

    static class staticinner{
        public void show1() {
            System.out.println("这是静态内部类");
        }
    }

    public static void main(String[] args) {
        Test190 t = new Test190();
        inner i = t. new inner();
        staticinner si  =new staticinner();
        i.show();
        si.show1();
    }
}

 

posted @ 2019-11-20 21:01  一位神秘丐帮  阅读(101)  评论(0编辑  收藏  举报