同步指的是多线程情况,一个线程块在一定时间内只能在一个线程内执行。java支持多线程执行,这就可能会导致两个或者多个线程访问同一个区域或者代码。同步是一个让所有并发的线程同步执行的过程。同步避免由共享内存不一致导致的内存错误,当一个方法被声明为同步的时候,线程保存着那个方法对象的监控,如果另一个线程正在执行这个同步方法,那么你的线程将会堵塞直到那个线程释放这个监控。
在java中同步由synchronized关键字实现的,你可以在你类中的方法或者块上使用synchronized关键字,关键字不能在类定义的变量或者属性上使用。
对象级别的锁
对象级别的锁是:只允许一个线程在类的实例上执行同步非静态方法或者非静态的代码块的一种机制这样做可以实例级别的数据线程安全。可以参看下边的代码:
public class DemoClass
{
public synchronized void demoMethod(){}
}
or
public class DemoClass
{
public void demoMethod(){
synchronized (this)
{
//other thread safe code
}
}
}
or
public class DemoClass
{
private final Object lock = new Object();
public void demoMethod(){
synchronized (lock)
{
//other thread safe code
}
}
}
类级别的锁
类级别的锁不允许多线程进入运行时的类的任何实例的同步块。这意味着在运行时有100个DemoClass的实例,然后有一个线程执行demoMethod()方法,那么其他线程的其他实例都会被阻塞,这样做可以使静态数据线程安全。
public class DemoClass
{
public synchronized static void demoMethod(){}
}
or
public class DemoClass
{
public void demoMethod(){
synchronized (DemoClass.class)
{
//other thread safe code
}
}
}
or
public class DemoClass
{
private final static Object lock = new Object();
public void demoMethod(){
synchronized (lock)
{
//other thread safe code
}
}
}
一些重要的提示
1、java中的同步保证没有两个线程可以一个同步方法,这需要同样的并发或者同步锁
2、synchronized关键字可以用在方法和代码块上。这些方法或者代码块可以使静态的也可以是非静态的。
3、当一个线程进入到java同步方法或者是代码块中,它需要一个锁,当离开的时候释放这个锁。同步方法的执行完毕、任何错误或者异常都会导致锁的释放。
4、java的synchronized关键字具有重进特性,这意味着,如果一个java同步方法调用了另一个同步方法,而这个方法需要同样的锁,那么当前有锁的线程可以直接进入方法而不需要锁。
5、java同步会在java对象中同步块为空的情况下抛出空指针异常。例如,在上边的例子中如果锁初始时为空,这个同步块将会抛出空指针异常
6、java中的同步方法会增加你程序的性能的消耗,所以只有在正真需要的时候才使用同步。同样,使用同步代码块的地方是你代码中关键的地方。
7、静态同步和非静态同步方法可以同步或并行的运行,因为他们的锁是在不同的对象上的。
8、根据java语言的规定,你不能在构造方法上使用synchronized关键字,这是非法的并且会导致编译错误
原文地址:http://howtodoinjava.com/2013/03/08/thread-synchronization-object-level-locking-and-class-level-locking/