具体实现的原理不赘述,博客很多,这里主要总结使用方法。
对于实例a1调用下面的非static函数而言,锁定的是a1,
对于A的实例a2而言,与a1没有关系,因此a2也可以在任何使用调用methon()方法。
对于A的静态函数staticMethod()而言,由于锁直接加在类A上,因此当通过实例a1调用staticMethod()就对对象A加锁,因此实例a2便无法访问staticMethod().
可以同时进入被synchronized(lock)的代码段; 对于静态的staticLock而言,由于静态变量的多个实例共享的,因此a1,a2有且仅有一个可以进入被synchronized(staticLock)修饰的代码段,必须等一方释放后另一方才能进入。
再继续引申,如果类A中定义了多个含有synchronized的代码块(函数),只要认定加锁的对象是不是被共享的来判定是否需要同步。
对于A的实例a1而言,method1(),method()2中被lock1加锁,因此多个线程同时运行同一个实例a1中的两个函数时必有一个阻塞(运行不同实例a1,a2的相通方法仍然不会阻塞),如果换成情况2,两个函数则没有同步问题;
假设有class A和对象的两个实例a1, a2;
synchronized 用法是作为函数修饰符或者函数内语句块修饰符,其实两者是相通的,
public synchronized void method()
{
//DO something
}
其实就相当于
public void method()
{
synchronized (this)
{
//DO something
}
}
对于非static的函数而言, A中的非static的synchronized函数
static synchronized void staticMethod()
{
//do something
}
其实相当于
static void staticMethod()
{
synchronized(A.class)
{
//do something
}
}
也就是说实际上我们只用探究一下synchronized代码块的问题。
对于实例a1调用下面的非static函数而言,锁定的是a1,
public void method()
{
synchronized (this)
{
//DO something
}
}
对于A的实例a2而言,与a1没有关系,因此a2也可以在任何使用调用methon()方法。
对于A的静态函数staticMethod()而言,由于锁直接加在类A上,因此当通过实例a1调用staticMethod()就对对象A加锁,因此实例a2便无法访问staticMethod().
static void staticMethod()
{
synchronized(A.class)
{
//do something
}
}
由此引申出来如下的用法,我们可以自己设定单独作为锁的变量,对于非静态lock而言,类A的两个对象实例a1,a2
可以同时进入被synchronized(lock)的代码段; 对于静态的staticLock而言,由于静态变量的多个实例共享的,因此a1,a2有且仅有一个可以进入被synchronized(staticLock)修饰的代码段,必须等一方释放后另一方才能进入。
class A
{
private byte[] lock = new byte[0];
private static byte[] staticLock = new byte[0];
public void method()
{
synchronized(lock)
{
//do something1
}
synchronized (staticLock)
{
//do something2
}
}
}
再继续引申,如果类A中定义了多个含有synchronized的代码块(函数),只要认定加锁的对象是不是被共享的来判定是否需要同步。
class A
{
private byte[] lock1 = new byte[0];
private byte[] lock2 = new byte[0];
public void method1()
{
synchronized(lock1)
{
//do something1
}
}
public void method2()
{
synchronized(lock1) // 情况2时改行被注释
//synchronized(lock2) //情况2时使用改行
{
//do something1
}
}
}
对于A的实例a1而言,method1(),method()2中被lock1加锁,因此多个线程同时运行同一个实例a1中的两个函数时必有一个阻塞(运行不同实例a1,a2的相通方法仍然不会阻塞),如果换成情况2,两个函数则没有同步问题;