为了保证数据的一致性即实现线程的安全性,java虚拟机提供了同步和锁机制。synchronized关键字是最基本的互斥同步手段。除此之外,还可以使用java.util.concurrent包中的重入锁(ReentrantLock)来实现同步。相比synchronized,ReentrantLock增加了一些高级功能,主要有等待可中断、可实现公平锁、锁可以绑定多个条件等。
见SynchronizedDemo.java的源码理解synchronized
/** * Synchronized理解: * 根据如下4个例子总结如下: * Synchronized修饰的方法和Synchronized(this)修饰的代码块功能是一样的,当使用Synchronized修饰的方法或Synchronized(this)修饰的代码块被调用时,当前的实例对象被锁住,因此没有其他线程可以调用该实例对象的这个或任何其他的Synchronized修饰的方法和Synchronized(this)修饰的代码块 * static Synchronized修饰的方法和Synchronized(*.class)修饰的代码块功能是一样的,当使用static Synchronized修饰的方法或Synchronized(*.class)修饰的代码块被调用时,当前的类对象(例子中的是Sync.class对象)被锁住,因此没有其他线程可以调用同一个类的的这个或任何其他的static Synchronized修饰的方法和Synchronized(*.class)修饰的代码块 **/ public class SynchronizedDemo{ /** * 例1: * 同一个对象: * 当一个线程进入一个对象A的synchronized方法的同时,其它线程不能进入该对象的任何synchronized方法 **/ private void showSynchronizedResult1(){ final Sync testSync1 = new Sync(); Thread thread1 = new Thread(new Runnable(){ @Override public void run(){ testSync1.run1(); } }); Thread thread2 = new Thread(new Runnable(){ @Override public void run(){ testSync1.run2(); } }); thread1.start(); thread2.start(); } /** * 例2: * 同一个对象: * 当一个线程进入一个对象A的synchronized方法的同时,其它线程可以进入该对象的普通方法 **/ private void showSynchronizedResult2(){ final Sync testSync1 = new Sync(); Thread thread1 = new Thread(new Runnable(){ @Override public void run(){ testSync1.run1(); } }); Thread thread3 = new Thread(new Runnable(){ @Override public void run(){ testSync1.run3(); } }); thread1.start(); thread3.start(); } /** * 例3: * 不同对象 * 当一个线程进入一个对象A的synchronized方法的同时,其它线程可以进入其他对象的synchronized方法,互不影响 **/ private void showSynchronizedResult3(){ final Sync testSync1 = new Sync(); final Sync testSync2 = new Sync(); Thread thread1 = new Thread(new Runnable(){ @Override public void run(){ testSync1.run1(); } }); Thread thread2 = new Thread(new Runnable(){ @Override public void run(){ testSync2.run2(); } }); thread1.start(); thread2.start(); } /** * 例4: * 当一个线程进入一个static synchronized方法的同时,其它线程不可以进入任何的static synchronized方法 **/ private void showStaticSynchronizedResult4(){ Thread thread1 = new Thread(new Runnable(){ @Override public void run(){ Sync.run4(); } }); Thread thread2 = new Thread(new Runnable(){ @Override public void run(){ Sync.run5(); } }); thread1.start(); thread2.start(); } public static void main(String args[]){ // 例1:多线程下同一对象的多个Synchronized方法 new SynchronizedDemo().showSynchronizedResult1(); // 例2:多线程下同一对象的Synchronized方法和普通方法 //new SynchronizedDemo().showSynchronizedResult2(); // 例3:多线程下不同对象的Synchronized方法 //new SynchronizedDemo().showSynchronizedResult3(); // 例4:多线程下的多个static Synchronized方法 //new SynchronizedDemo().showStaticSynchronizedResult4(); } } class Sync{ public synchronized void run1(){ for (int i = 0; i < 5; i++){ System.out.println("execute run1"); sleepOneSec(); } } public synchronized void run2(){ for (int i = 0; i < 5; i++){ System.out.println("execute run2"); sleepOneSec(); } } public void run3(){ for (int i = 0; i < 5; i++){ System.out.println("execute run3"); sleepOneSec(); } } public static synchronized void run4(){ for (int i = 0; i < 5; i++){ System.out.println("execute run4"); sleepOneSec(); } } public static synchronized void run5(){ for (int i = 0; i < 5; i++){ System.out.println("execute run5"); sleepOneSec(); } } private static void sleepOneSec(){ try{ Thread.sleep(1000); }catch (InterruptedException e){ e.printStackTrace(); } } }