java synchronized
锁
在并发环境下,解决共享资源冲突问题时,可以考虑使用锁机制。
synchronized同步
当使用同步块时,如果方法下的同步块都同步到一个对象上的锁,则所有的任务(线程)只能互斥的进入这些同步块。
举例说明:
1、Test1.java演示了4个线程(包括main线程)试图进入某个类的三个不同的方法的同步块中
线程1调用method1
线程2调用method2
线程3调用method3
main也调用method3
不仅仅线程3和main是互斥的,实际上4个线程都是互斥的,因为他们都同步到了一个对象上(当前对象 synchronized (this)),所以对它们的方法依然是互斥的。
2、Test2.java演示了2个线程(包括main线程)试图进入某个类的同一个同步方法中,另外两个线程进入非同步方法。
线程1调用同步方法method1
线程2调用method2
线程3调用method3
main调用同步方法method1
线程1和main是互斥的,
如果先启动线程1,则线程1,线程2,线程3是独立进行的。执行完线程1,才会执行main
如果先启动线程main,则main,线程2,线程3是独立进行的。执行完main,才会执行线程1
3、Test3.java演示了三个线程试图进入某个类的三个不同的方法的同步块中,这些同步块处在不同的方法中,并且是同步到三个不同的对象(synchronized (obj1),synchronized(obj2),synchronized (obj3)),所以这三个线程是独立进行的,并不是互斥的。
package com.jialin; /** * 抽象测试类 * @author jialin * */ public abstract class AbstractTest { public void Method1() {} public void Method2() {} public void Method3() {} }
package com.jialin; import java.util.concurrent.TimeUnit; /** * 测试java 锁 * @author jialin * */ public class Test1 extends AbstractTest{ public void Method1() { //-----这一部分未加锁,可以运行到------begin--- System.out.println(Thread.currentThread().getName() + ":not synchronized part in Method1()"); //-----这一部分未加锁,可以运行到------end--- synchronized (this) { for (int i = 0; i < 5; i++) { System.out.println(Thread.currentThread().getName() + ":synchronized in Method1("+i+")"); try { TimeUnit.SECONDS.sleep(3); } catch (InterruptedException e) { e.printStackTrace(); } } } } public void Method2() { //-----这一部分未加锁,可以运行到------begin--- System.out.println(Thread.currentThread().getName() + ":not synchronized part in Method2()"); //-----这一部分未加锁,可以运行到------end--- synchronized (this) { for (int i = 0; i < 5; i++) { System.out.println(Thread.currentThread().getName() + ":synchronized in Method2("+i+")"); try { TimeUnit.SECONDS.sleep(3); } catch (InterruptedException e) { e.printStackTrace(); } } } } public void Method3() { //-----这一部分未加锁,可以运行到------begin--- System.out.println(Thread.currentThread().getName() + ":not synchronized part in Method3()"); //-----这一部分未加锁,可以运行到------end--- synchronized (this) { for (int i = 0; i < 5; i++) { System.out.println(Thread.currentThread().getName() + ":synchronized in Method3("+i+")"); try { TimeUnit.SECONDS.sleep(3); } catch (InterruptedException e) { e.printStackTrace(); } } } } public static void main(String[] args) { //初始化Test1对象 final AbstractTest ts = new Test1(); //线程1 Thread1 thread1=new Thread1(ts); thread1.start(); //线程2 Thread2 thread2=new Thread2(ts); thread2.start(); //线程3 Thread3 thread3=new Thread3(ts); thread3.start(); //main线程 ts.Method3(); } }
运行结果:
Thread-0:not synchronized part in Method1()
Thread-0:synchronized in Method1(0)
main:not synchronized part in Method3()
Thread-1:not synchronized part in Method2()
Thread-2:not synchronized part in Method3()
Thread-0:synchronized in Method1(1)
Thread-0:synchronized in Method1(2)
Thread-0:synchronized in Method1(3)
Thread-0:synchronized in Method1(4)
Thread-2:synchronized in Method3(0)
Thread-2:synchronized in Method3(1)
Thread-2:synchronized in Method3(2)
Thread-2:synchronized in Method3(3)
Thread-2:synchronized in Method3(4)
Thread-1:synchronized in Method2(0)
Thread-1:synchronized in Method2(1)
Thread-1:synchronized in Method2(2)
Thread-1:synchronized in Method2(3)
Thread-1:synchronized in Method2(4)
main:synchronized in Method3(0)
main:synchronized in Method3(1)
main:synchronized in Method3(2)
main:synchronized in Method3(3)
main:synchronized in Method3(4)
package com.jialin; import java.util.concurrent.TimeUnit; public class Test2 extends AbstractTest { public synchronized void Method1() { for (int i = 0; i < 5; i++) { System.out.println(Thread.currentThread().getName() + ":synchronized in Method1("+i+")"); try { TimeUnit.SECONDS.sleep(3); } catch (InterruptedException e) { e.printStackTrace(); } } } public void Method2() { for (int i = 0; i < 5; i++) { System.out.println(Thread.currentThread().getName() + ":no synchronized in Method2("+i+")"); try { TimeUnit.SECONDS.sleep(3); } catch (InterruptedException e) { e.printStackTrace(); } } } public void Method3() { for (int i = 0; i < 5; i++) { System.out.println(Thread.currentThread().getName() + ":no synchronized in Method3("+i+")"); try { TimeUnit.SECONDS.sleep(3); } catch (InterruptedException e) { e.printStackTrace(); } } } public static void main(String[] args) { // 初始化Test1对象 final AbstractTest ts = new Test2(); // 线程1 Thread1 thread1 = new Thread1(ts); thread1.start(); // 线程2 Thread2 thread2 = new Thread2(ts); thread2.start(); //线程3 Thread3 thread3=new Thread3(ts); thread3.start(); // main线程 ts.Method1(); } }
运行结果:
Thread-0:synchronized in Method1(0)
Thread-1:no synchronized in Method2(0)
Thread-2:no synchronized in Method3(0)
Thread-0:synchronized in Method1(1)
Thread-1:no synchronized in Method2(1)
Thread-2:no synchronized in Method3(1)
Thread-1:no synchronized in Method2(2)
Thread-0:synchronized in Method1(2)
Thread-2:no synchronized in Method3(2)
Thread-1:no synchronized in Method2(3)
Thread-0:synchronized in Method1(3)
Thread-2:no synchronized in Method3(3)
Thread-1:no synchronized in Method2(4)
Thread-2:no synchronized in Method3(4)
Thread-0:synchronized in Method1(4)
main:synchronized in Method1(0)
main:synchronized in Method1(1)
main:synchronized in Method1(2)
main:synchronized in Method1(3)
main:synchronized in Method1(4)
package com.jialin; import java.util.concurrent.TimeUnit; public class Test3 extends AbstractTest { private Object obj1=new Object(); private Object obj2=new Object(); private Object obj3=new Object(); public void Method1() { synchronized (obj1) { for (int i = 0; i < 5; i++) { System.out.println(Thread.currentThread().getName() + ":synchronized in Method1("+i+")"); try { TimeUnit.SECONDS.sleep(3); } catch (InterruptedException e) { e.printStackTrace(); } } } } public void Method2() { synchronized (obj2) { for (int i = 0; i < 5; i++) { System.out.println(Thread.currentThread().getName() + ":synchronized in Method2("+i+")"); try { TimeUnit.SECONDS.sleep(3); } catch (InterruptedException e) { e.printStackTrace(); } } } } public void Method3() { synchronized (obj3) { for (int i = 0; i < 5; i++) { System.out.println(Thread.currentThread().getName() + ":synchronized in Method3("+i+")"); try { TimeUnit.SECONDS.sleep(3); } catch (InterruptedException e) { e.printStackTrace(); } } } } public static void main(String[] args) { // 初始化Test1对象 final AbstractTest ts = new Test3(); // 线程1 Thread1 thread1 = new Thread1(ts); thread1.start(); // 线程2 Thread2 thread2 = new Thread2(ts); thread2.start(); //线程3 Thread3 thread3=new Thread3(ts); thread3.start(); } }
运行结果:
Thread-0:synchronized in Method1(0)
Thread-1:synchronized in Method2(0)
Thread-2:synchronized in Method3(0)
Thread-1:synchronized in Method2(1)
Thread-0:synchronized in Method1(1)
Thread-2:synchronized in Method3(1)
Thread-0:synchronized in Method1(2)
Thread-2:synchronized in Method3(2)
Thread-1:synchronized in Method2(2)
Thread-0:synchronized in Method1(3)
Thread-2:synchronized in Method3(3)
Thread-1:synchronized in Method2(3)
Thread-0:synchronized in Method1(4)
Thread-2:synchronized in Method3(4)
Thread-1:synchronized in Method2(4)
package com.jialin; public class Thread1 extends Thread { private AbstractTest ts; public Thread1(AbstractTest ts) { this.ts=ts; } @Override public void run() { ts.Method1(); } }
package com.jialin; public class Thread2 extends Thread { private AbstractTest ts; public Thread2(AbstractTest ts) { this.ts = ts; } @Override public void run() { ts.Method2(); } }
package com.jialin; public class Thread3 extends Thread { private AbstractTest ts; public Thread3(AbstractTest ts) { this.ts = ts; } @Override public void run() { ts.Method3(); } }