Java synchronized解析

多线程三大特性:多线程

可见性、原子性、有序性ide

synchronize的特性:spa

一、同一时刻只有一个线程访问临界资源线程

二、其它未获取到锁执行权的线程必须排队等待code

三、保证共享资源的原子性、可见性和有序性对象

四、进入synchronized范围内自动加锁,synchronized做用域外锁自动消除,即便异常也会释放锁blog

 synchronize加锁的方式:资源

  • 对于普通同步方法,锁是当前实例对象。作用域

  • 对于静态同步方法,锁是当前类的Class对象。同步

  • 对于同步方法块,锁是Synchonized括号里配置的对象。

 

经过具体的例子来看一下

首先是普通方法:

class NoSyncTest { public void method1() { Log.i("sync", "method 1 start"); try { Log.i("sync", "method 1 execute"); Thread.sleep(3000); } catch (InterruptedException e) { // TODO Auto-generated catch block
 e.printStackTrace(); } Log.i("sync", "method 1 end"); } public void method2() { Log.i("sync", "method 2 start"); try { Log.i("sync", "method 2 execute"); Thread.sleep(500); } catch (InterruptedException e) { // TODO Auto-generated catch block
 e.printStackTrace(); } Log.i("sync", "method 2 end"); } } private void noSyncTest() { final NoSyncTest test = new NoSyncTest(); Thread thread1 = new Thread(new Runnable() { @Override public void run() { test.method1(); } }); Thread thread2 = new Thread(new Runnable() { @Override public void run() { test.method2(); } }); thread1.start(); thread2.start(); }

这是一个没有任何同步的方法,NoSyncTest这个类有两个方法method1和method2,分别执行睡3s和0.5s的动做,而后再两个线程中分别调用这个类的实例test的两个方法,看一下结果:

 

能够看到method2和method1同时执行,method2由于sleep的时间短因此先结束。

再看一下普通方法同步:

class MethodSyncTest { public synchronized void method1() { Log.i("sync", "method 1 start"); try { Log.i("sync", "method 1 execute"); Thread.sleep(3000); } catch (InterruptedException e) { // TODO Auto-generated catch block
 e.printStackTrace(); } Log.i("sync", "method 1 end"); } public synchronized void method2() { Log.i("sync", "method 2 start"); try { Log.i("sync", "method 2 execute"); Thread.sleep(500); } catch (InterruptedException e) { // TODO Auto-generated catch block
 e.printStackTrace(); } Log.i("sync", "method 2 end"); } } private void MethodSyncTest() { final MethodSyncTest test = new MethodSyncTest(); Thread thread1 = new Thread(new Runnable() { @Override public void run() { test.method1(); } }); Thread thread2 = new Thread(new Runnable() { @Override public void run() { test.method2(); } }); thread1.start(); thread2.start(); 

synchronize修饰的method1和method2,其余不变,看一下结果:

method1先执行而后3s以后结束了method2才开始执行。(注意这个地方不能new 不一样的对象来调用方法,由于修饰普通方法本质是对对象的同步加锁。

看一下第三种静态同步方法:

static class StaticMethodSyncTest { public static synchronized void method1() { Log.i("sync", "method 1 start"); try { Log.i("sync", "method 1 execute"); Thread.sleep(3000); } catch (InterruptedException e) { // TODO Auto-generated catch block
 e.printStackTrace(); } Log.i("sync", "method 1 end"); } public static synchronized void method2() { Log.i("sync", "method 2 start"); try { Log.i("sync", "method 2 execute"); Thread.sleep(500); } catch (InterruptedException e) { // TODO Auto-generated catch block
 e.printStackTrace(); } Log.i("sync", "method 2 end"); } public static synchronized void method3() { Log.i("sync", "method 3 start"); try { Log.i("sync", "method 3 execute"); Thread.sleep(1000); } catch (InterruptedException e) { // TODO Auto-generated catch block
 e.printStackTrace(); } Log.i("sync", "method 3 end"); } } private void StaticMethodSyncTest() { final StaticMethodSyncTest test1 = new StaticMethodSyncTest(); final StaticMethodSyncTest test2 = new StaticMethodSyncTest(); Thread thread1 = new Thread(new Runnable() { @Override public void run() { test1.method1(); } }); Thread thread2 = new Thread(new Runnable() { @Override public void run() { test2.method2(); } }); Thread thread3 = new Thread(new Runnable() { @Override public void run() { StaticMethodSyncTest.method3(); } }); thread1.start(); thread2.start(); thread3.start(); }

static修饰方法至关于这个方法是类方法,能够直接经过类名.方法名调用。咱们在这new出了test1和test2两个对象分别调用method1和method2,以及经过类名.方法名调用method3,看一下结果

method一、method二、method3顺序执行。(同步静态方法的本质是锁的当前类

相关文章
相关标签/搜索