一、静态同步synchronized方法与synchronized(class)代码块
1、静态同步synchronized方法
关键字synchronized可以应用在static静态方法上,是对当前的java文件对应的Class类进行持锁。
public class HasSelfPrivateNum {
//对静态方法加锁
public synchronized static void addI(String userName,NoSysnTest noSysnTest){
System.out.println("sleep end threadName="+Thread.currentThread().getName()+" time="+System.currentTimeMillis());
}
}
synchronized关键字加到static静态方法上是给Class类上锁。
由于一个class不论被实例化多少次,其中的静态方法和静态变量在内存中都只有一份。所以,一旦一个静态的方法被申明为synchronized。此类所有的实例化对象在调用此方法,共用同一把锁,我们称之为类锁。
public class HasSelfPrivateNum {
//静态方法同步
public synchronized static void addI(String userName,NoSysnTest noSysnTest){
System.out.println("sleep end threadName="+Thread.currentThread().getName()+" time="+System.currentTimeMillis());
}
//非静态方法同步
public synchronized void addA(){
System.out.println("threadName="+Thread.currentThread().getName()+" time="+System.currentTimeMillis());
}
}
//不同的线程调用这两个同步方法时,出现异步的情况,因为是不同的锁。一个是对象锁,一个是类锁。
二、synchronized(class)代码块
public class HasSelfPrivateNum {
//静态代码块
public static void addI(String userName,NoSysnTest noSysnTest){
//类 作为监控器
synchronized (HasSelfPrivateNum.class){
System.out.println("sleep end threadName="+Thread.currentThread().getName()+" time="+System.currentTimeMillis());
}
}
}
三、数据类型String的常量池特性
在JVM中具有String常量池缓存的功能,如果两个线程具有相同的String值,那么两个线程会持有相同的锁,容易造成死锁。
在大多数情况下,同步synchronized代码块都不使用String作为锁对象,而改用其他,比如new Object()实例化对象,但它并不放入缓存中。
public class HasSelfPrivateNum {
public static void addI(String userName){
//不建议使用String类型作为锁对象
synchronized (userName){
System.out.println("sleep end threadName="+Thread.currentThread().getName()+" time="+System.currentTimeMillis());
}
}
}
四、同步synchronized方法无限等待与解决
同步方法容易造成死循环。
public class HasSelfPrivateNum {
public synchronized static void addI(String userName){
//容易造成死锁
while(true) {
System.out.println("sleep end threadName=" + Thread.currentThread().getName() + " time=" + System.currentTimeMillis());
}
}
}
可以使用同步代码块来解决:
public class HasSelfPrivateNum {
Object object=new Object();
public void addI(String userName){
//不同的锁对象
synchronized (object){
while(true) {
System.out.println("sleep end threadName=" + Thread.currentThread().getName() + " time=" + System.currentTimeMillis());
}
}
}
}
五、多线程的死锁
不同的线程都在等待根本不可能被释放的锁,从而导致所有的任务都无法继续完成,会造成线程的”假死”。
六、内置类与静态内置类
1、内置类
public class PublicClass {
private String username;
//内置类,如果实现不在一个包中,则需要声明为public
//实现使用:PrivateClass priClass=new PublicClass ().new PrivateClass();
class PrivateClass{
private String age;
}
//静态内置类
//PrivateClass priClass=new PrivateClass();
static class PrivateClass{
private String address;
}
}
七、内置类与同步(对象锁)
public class PublicClass {
//内置类
class PrivateClass{
public void method1(Object object){
synchronized (object){
System.out.print("");
}
}
public synchronized void method2(){
System.out.print("");
}
}
}
//持有不同的对象监视器,结果是异步的。