线程固有锁
同步方法锁定在物体上的方法
synchronized void methodA() {
....
}
在某种程度上相当于
void methodA() {
synchronized (this) {
....
}
}
内在锁是在对象上:
class A
{
public synchronized void method1(){...}
public synchronized void method2(){...}
}
如果线程A是在方法1那么threadB不能输入method2。
我希望,*允许我为你的最后一行加上+10。 :) – UnKnown 2015-10-03 22:08:32
锁是对象的一部分。每个对象具有一个和它可以被锁定在两种方式:
- 使用关于类的实例方法的改性剂来锁定相关联的对象
- 使用
synchronized(object) {}
块
类似地,你可以锁定一个对象的类而不是对象本身(为了解修改器,用static
方法分开提及):
- 使用的类的一个静态方法的改性剂以锁定类
- 使用
synchronized(clazz) {}
块,其中clazz
是Object
在Java中,一个内部锁是由每个使用
synchronized关键字中的每一个使用与两种类型的内部锁中的一个相关联的同步关键字的暗示:
“实例锁”,连接到单个对象
“静态锁”,附加到类
如果一个方法被声明为同步的,那么它会获得任一实例锁或者调用时的静态锁,根据它是实例方法还是静态方法。
这两种类型的锁具有相似的行为,但彼此完全独立。
获取实例锁只会阻止其他线程调用同步实例方法;它不会阻止其他线程调用未同步的方法,也不会阻止它们调用静态同步方法。
同样,获取静态锁只会阻止其他线程调用静态同步方法;它不会阻止其他线程调用未同步的方法,也不会阻止它们调用同步的实例方法。
在方法头之外,synchronized(this)获取实例锁。
静态锁可以的方法报头之外以两种方式获得:
同步(Blah.class),使用类字面
同步(this.getClass()),如果对象可用
private int count = 0;
public synchronized void countFunc(){
count++;
}
Thread t1 = new Thread(new Runnable(){
public void run(){
for(int i=0;i<1000;i++){
countFunc();
}}});
Thread t2 = new Thread(new Runnable(){
public void run(){
for(int i=0;i<1000;i++){
countFunc();
}}});
在上面的例子中,我有2个线程试图增加count的值。并且为了防止线程交错,我试图通过使用同步关键字来获取固有锁。
决定性, 在这个例子中,锁是方法块countFunc与同步关键字和锁是上的计数变量。 希望这可以帮助
锁在对象上。
看一看Java教程页面上intrinsic locks
每个对象都有一个与之关联的内部锁。按照惯例,需要独占且一致地访问对象字段的线程在访问对象之前必须先获取对象的内部锁,然后在完成内部锁时释放内部锁。据说一个线程拥有它获得锁定和释放锁定之间的固有锁定。
只要线程拥有内部锁,其他线程就不会获得相同的锁。另一个线程在尝试获取锁时会阻塞。
两种方式使用内部锁:
-
同步方法:
当一个线程调用方法,它会自动获取内部锁该方法的对象,当方法返回时释放它。
例如
public synchronized void incrementCounter(){ ++counter; }
-
同步语句
不同于方法,语句必须指定提供了内部锁
public int getCounter(){ synchronized(this){ return counter; } }
完整的示例对象:
public class SynchronizedDemo{ private int counter = 0; public SynchronizedDemo(){ } public synchronized void incrementCounter(){ ++counter; } public int getCounter(){ synchronized(this){ return counter; } } public static void main(String[] args){ SynchronizedDemo object = new SynchronizedDemo(); for (int i=0; i < 5; i++){ Thread t = new Thread(new SimpleRunnable(object)); t.start(); } } } class SimpleRunnable implements Runnable{ private SynchronizedDemo object; public SimpleRunnable(SynchronizedDemo obj){ this.object = obj; } public void run(){ object.incrementCounter(); System.out.println("Counter:"+object.getCounter()); } }
注意:本示例仅用于展示使用内部锁的不同方式。对于这种类型的用例,使用AtomicInteger作为计数器变量是正确的方法。
每个对象都有一个内部锁。这两个语句是等价的,因为两者都在包含methodA()的对象的内部锁定上进行同步。 – Brandon 2013-02-01 22:06:10
向不懂理解同步方法的人解释同步语句不是一个好主意。这使我更加困惑。 – 2014-07-12 02:11:45