- synchronized关键字可以作为函数的修饰符,也可作为函数内的语句,也就是平时说的同步方法和同步语句块。如果再细的分类,synchronized可作用于instance变量、object reference(对象引用)、static函数和class literals(类名称字面常量)身上。
- synchronized取得的锁都是对象;每个对象只有一个锁(lock)与之相关联;实现同步是要很大的系统开销作为代价的,甚至可能造成死锁,所以尽量避免无谓的同步控制。
- 实际上,如果在类中某方法或某代码块中有 synchronized,那么在生成一个该类实例后,该类也就有一个监视块,监视线程并发访问改实例synchronized保护块。而static synchronized则是该类的所有实例公用一个监视块,静态同步方法和非静态同步方法持有的是不同的锁,前者是类锁,后者是对象锁。这便是两个的区别了
一、synchronized的5种用法:
1.方法声明时使用,线程获得的是成员锁.
2.对某一代码块使用,synchronized后跟括号,括号里是变量,线程获得的是成员锁.
3.synchronized后面括号里是一对象,此时,线程获得的是对象锁.
4.synchronized后面括号里是类,此时,线程获得的是对象锁.
5、方法静态是class锁,非静态是实例对象锁
synchronized作为修饰符锁方法
二、synchronized锁重入
关键字synchronized拥有锁重入的功能。所谓锁重入的意思就是:当一个线程得到一个对象锁后,再次请求此对象锁时时可以再次得到该对象的锁的
public class ThreadDomain16
{
public synchronized void print1()
{
System.out.println("ThreadDomain16.print1()");
print2();
}
public synchronized void print2()
{
System.out.println("ThreadDomain16.print2()");
print3();
}
public synchronized void print3()
{
System.out.println("ThreadDomain16.print3()");
}
}
public class MyThread16 extends Thread
{
public void run()
{
ThreadDomain16 td = new ThreadDomain16();
td.print1();
}
}
public static void main(String[] args)
{
MyThread16 mt = new MyThread16();
mt.start();
}
看一下运行结果:
ThreadDomain16.print1()
ThreadDomain16.print2()
ThreadDomain16.print3()
这种锁重入的机制,也支持在父子类继承的环境中。
三、异常自动释放锁
当一个线程执行的代码出现异常时,其所持有的锁会自动释放。模拟的是把一个long型数作为除数,从MAX_VALUE开始递减,直至减为0,从而产生ArithmeticException