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