Java:使用synchronized和Lock对象获取对象锁


  1.   
  2. 在并发环境下,解决共享资源冲突问题时,可以考虑使用锁机制。   
  3. 1.对象的锁   
  4. 所有对象都自动含有单一的锁。   
  5. JVM负责跟踪对象被加锁的次数。如果一个对象被解锁,其计数变为0。在任务(线程)第一次给对象加锁的时候,计数变为1。每当这个相同的任务(线程)在此对象上获得锁时,计数会递增。   
  6. 只有首先获得锁的任务(线程)才能继续获取该对象上的多个锁。   
  7. 每当任务离开一个synchronized方法,计数递减,当计数为0的时候,锁被完全释放,此时别的任务就可以使用此资源。   
  8. 2.synchronized同步块   
  9. 2.1同步到单一对象锁   
  10. 当使用同步块时,如果方法下的同步块都同步到一个对象上的锁,则所有的任务(线程)只能互斥的进入这些同步块。   
  11. Resource1.java演示了三个线程(包括main线程)试图进入某个类的三个不同的方法的同步块中,虽然这些同步块处在不同的方法中,但由于是同步到同一个对象(当前对象 synchronized (this)),所以对它们的方法依然是互斥的。   
  12. Resource1.java   
  13. package com.zj.lock;   
  14. import java.util.concurrent.TimeUnit;   
  15.     
  16. public class Resource1 {   
  17.     public void f() {   
  18.        // other operations should not be locked...   
  19.        System.out.println(Thread.currentThread().getName()   
  20.               + ":not synchronized in f()");   
  21.        synchronized (this) {   
  22.            for (int i = 0; i < 5; i++) {   
  23.               System.out.println(Thread.currentThread().getName()   
  24.                      + ":synchronized in f()");   
  25.               try {   
  26.                   TimeUnit.SECONDS.sleep(3);   
  27.               } catch (InterruptedException e) {   
  28.                   e.printStackTrace();   
  29.               }   
  30.            }   
  31.        }   
  32.     }   
  33.     
  34.     public void g() {   
  35.        // other operations should not be locked...   
  36.        System.out.println(Thread.currentThread().getName()   
  37.               + ":not synchronized in g()");   
  38.        synchronized (this) {   
  39.            for (int i = 0; i < 5; i++) {   
  40.               System.out.println(Thread.currentThread().getName()   
  41.                      + ":synchronized in g()");   
  42.               try {   
  43.                   TimeUnit.SECONDS.sleep(3);   
  44.               } catch (InterruptedException e) {   
  45.                   e.printStackTrace();   
  46.               }   
  47.            }   
  48.        }   
  49.     }   
  50.     
  51.     public void h() {   
  52.        // other operations should not be locked...   
  53.        System.out.println(Thread.currentThread().getName()   
  54.               + ":not synchronized in h()");   
  55.        synchronized (this) {   
  56.            for (int i = 0; i < 5; i++) {   
  57.               System.out.println(Thread.currentThread().getName()   
  58.                      + ":synchronized in h()");   
  59.               try {   
  60.                   TimeUnit.SECONDS.sleep(3);   
  61.               } catch (InterruptedException e) {   
  62.                   e.printStackTrace();   
  63.               }   
  64.            }   
  65.        }   
  66.     }   
  67.     
  68.     public static void main(String[] args) {   
  69.        final Resource1 rs = new Resource1();   
  70.     
  71.        new Thread() {   
  72.            public void run() {   
  73.               rs.f();   
  74.            }   
  75.        }.start();   
  76.     
  77.        new Thread() {   
  78.            public void run() {   
  79.               rs.g();   
  80.            }   
  81.        }.start();   
  82.     
  83.        rs.h();   
  84.     }   
  85. }   
  86. 结果:   
  87. Thread-0:not synchronized in f()   
  88. Thread-0:synchronized in f()   
  89. main:not synchronized in h()   
  90. Thread-1:not synchronized in g()   
  91. Thread-0:synchronized in f()   
  92. Thread-0:synchronized in f()   
  93. Thread-0:synchronized in f()   
  94. Thread-0:synchronized in f()   
  95. Thread-1:synchronized in g()   
  96. Thread-1:synchronized in g()   
  97. Thread-1:synchronized in g()   
  98. Thread-1:synchronized in g()   
  99. Thread-1:synchronized in g()   
  100. main:synchronized in h()   
  101. main:synchronized in h()   
  102. main:synchronized in h()   
  103. main:synchronized in h()   
  104. main:synchronized in h()   
  105. 2.2 同步到多个对象锁   
  106. Resource1.java演示了三个线程(包括main线程)试图进入某个类的三个不同的方法的同步块中,这些同步块处在不同的方法中,并且是同步到三个不同的对象(synchronized (this),synchronized (syncObject1),synchronized (syncObject2)),所以对它们的方法中的临界资源访问是独立的。   
  107. Resource2.java   
  108. package com.zj.lock;   
  109. import java.util.concurrent.TimeUnit;   
  110.     
  111. public class Resource2 {   
  112.     private Object syncObject1 = new Object();   
  113.     private Object syncObject2 = new Object();   
  114.     
  115.     public void f() {   
  116.        // other operations should not be locked...   
  117.        System.out.println(Thread.currentThread().getName()   
  118.               + ":not synchronized in f()");   
  119.        synchronized (this) {   
  120.            for (int i = 0; i < 5; i++) {   
  121.               System.out.println(Thread.currentThread().getName()   
  122.                      + ":synchronized in f()");   
  123.               try {   
  124.                   TimeUnit.SECONDS.sleep(3);   
  125.               } catch (InterruptedException e) {   
  126.                   e.printStackTrace();   
  127.               }   
  128.            }   
  129.        }   
  130.     }   
  131.     
  132.     public void g() {   
  133.        // other operations should not be locked...   
  134.        System.out.println(Thread.currentThread().getName()   
  135.               + ":not synchronized in g()");   
  136.        synchronized (syncObject1) {   
  137.            for (int i = 0; i < 5; i++) {   
  138.               System.out.println(Thread.currentThread().getName()   
  139.                      + ":synchronized in g()");   
  140.               try {   
  141.                   TimeUnit.SECONDS.sleep(3);   
  142.               } catch (InterruptedException e) {   
  143.                   e.printStackTrace();   
  144.               }   
  145.            }   
  146.        }   
  147.     }   
  148.     
  149.     public void h() {   
  150.        // other operations should not be locked...   
  151.        System.out.println(Thread.currentThread().getName()   
  152.               + ":not synchronized in h()");   
  153.        synchronized (syncObject2) {   
  154.            for (int i = 0; i < 5; i++) {   
  155.               System.out.println(Thread.currentThread().getName()   
  156.                      + ":synchronized in h()");   
  157.               try {   
  158.                   TimeUnit.SECONDS.sleep(3);   
  159.               } catch (InterruptedException e) {   
  160.                   e.printStackTrace();   
  161.               }   
  162.            }   
  163.        }   
  164.     }   
  165.     
  166.     public static void main(String[] args) {   
  167.        final Resource2 rs = new Resource2();   
  168.     
  169.        new Thread() {   
  170.            public void run() {   
  171.               rs.f();   
  172.            }   
  173.        }.start();   
  174.     
  175.        new Thread() {   
  176.            public void run() {   
  177.               rs.g();   
  178.            }   
  179.        }.start();   
  180.     
  181.        rs.h();   
  182.     }   
  183. }   
  184. 结果:   
  185. Thread-0:not synchronized in f()   
  186. Thread-0:synchronized in f()   
  187. main:not synchronized in h()   
  188. main:synchronized in h()   
  189. Thread-1:not synchronized in g()   
  190. Thread-1:synchronized in g()   
  191. Thread-0:synchronized in f()   
  192. main:synchronized in h()   
  193. Thread-1:synchronized in g()   
  194. Thread-0:synchronized in f()   
  195. main:synchronized in h()   
  196. Thread-1:synchronized in g()   
  197. Thread-0:synchronized in f()   
  198. main:synchronized in h()   
  199. Thread-1:synchronized in g()   
  200. Thread-0:synchronized in f()   
  201. main:synchronized in h()   
  202. Thread-1:synchronized in g()   
  203. 3.Lock对象锁   
  204. 除了使用synchronized外,还可以使用Lock对象来创建临界区。Resource3.java的演示效果同Resource1.java;Resource4.java的演示效果同Resource2.java。   
  205. Resource3.java   
  206. package com.zj.lock;   
  207. import java.util.concurrent.TimeUnit;   
  208. import java.util.concurrent.locks.Lock;   
  209. import java.util.concurrent.locks.ReentrantLock;   
  210.     
  211. public class Resource3 {   
  212.     private Lock lock = new ReentrantLock();   
  213.     
  214.     public void f() {   
  215.        // other operations should not be locked...   
  216.        System.out.println(Thread.currentThread().getName()   
  217.               + ":not synchronized in f()");   
  218.        lock.lock();   
  219.        try {   
  220.            for (int i = 0; i < 5; i++) {   
  221.               System.out.println(Thread.currentThread().getName()   
  222.                      + ":synchronized in f()");   
  223.               try {   
  224.                   TimeUnit.SECONDS.sleep(3);   
  225.               } catch (InterruptedException e) {   
  226.                   e.printStackTrace();   
  227.               }   
  228.            }   
  229.        } finally {   
  230.            lock.unlock();   
  231.        }   
  232.     }   
  233.     
  234.     public void g() {   
  235.        // other operations should not be locked...   
  236.        System.out.println(Thread.currentThread().getName()   
  237.               + ":not synchronized in g()");   
  238.        lock.lock();   
  239.        try {   
  240.            for (int i = 0; i < 5; i++) {   
  241.               System.out.println(Thread.currentThread().getName()   
  242.                      + ":synchronized in g()");   
  243.               try {   
  244.                   TimeUnit.SECONDS.sleep(3);   
  245.               } catch (InterruptedException e) {   
  246.                   e.printStackTrace();   
  247.               }   
  248.            }   
  249.        } finally {   
  250.            lock.unlock();   
  251.        }   
  252.     }   
  253.     
  254.     public void h() {   
  255.        // other operations should not be locked...   
  256.        System.out.println(Thread.currentThread().getName()   
  257.               + ":not synchronized in h()");   
  258.        lock.lock();   
  259.        try {   
  260.            for (int i = 0; i < 5; i++) {   
  261.               System.out.println(Thread.currentThread().getName()   
  262.                      + ":synchronized in h()");   
  263.               try {   
  264.                   TimeUnit.SECONDS.sleep(3);   
  265.               } catch (InterruptedException e) {   
  266.                   e.printStackTrace();   
  267.               }   
  268.            }   
  269.        } finally {   
  270.            lock.unlock();   
  271.        }   
  272.     }   
  273.     
  274.     public static void main(String[] args) {   
  275.        final Resource3 rs = new Resource3();   
  276.     
  277.        new Thread() {   
  278.            public void run() {   
  279.               rs.f();   
  280.            }   
  281.        }.start();   
  282.     
  283.        new Thread() {   
  284.            public void run() {   
  285.               rs.g();   
  286.            }   
  287.        }.start();   
  288.     
  289.        rs.h();   
  290.     }   
  291. }   
  292. 结果:   
  293. Thread-0:not synchronized in f()   
  294. Thread-0:synchronized in f()   
  295. main:not synchronized in h()   
  296. Thread-1:not synchronized in g()   
  297. Thread-0:synchronized in f()   
  298. Thread-0:synchronized in f()   
  299. Thread-0:synchronized in f()   
  300. Thread-0:synchronized in f()   
  301. main:synchronized in h()   
  302. main:synchronized in h()   
  303. main:synchronized in h()   
  304. main:synchronized in h()   
  305. main:synchronized in h()   
  306. Thread-1:synchronized in g()   
  307. Thread-1:synchronized in g()   
  308. Thread-1:synchronized in g()   
  309. Thread-1:synchronized in g()   
  310. Thread-1:synchronized in g()   
  311. Resource4.java   
  312. package com.zj.lock;   
  313. import java.util.concurrent.TimeUnit;   
  314. import java.util.concurrent.locks.Lock;   
  315. import java.util.concurrent.locks.ReentrantLock;   
  316.     
  317. public class Resource4 {   
  318.     private Lock lock1 = new ReentrantLock();   
  319.     private Lock lock2 = new ReentrantLock();   
  320.     private Lock lock3 = new ReentrantLock();   
  321.     
  322.     public void f() {   
  323.        // other operations should not be locked...   
  324.        System.out.println(Thread.currentThread().getName()   
  325.               + ":not synchronized in f()");   
  326.        lock1.lock();   
  327.        try {   
  328.            for (int i = 0; i < 5; i++) {   
  329.               System.out.println(Thread.currentThread().getName()   
  330.                      + ":synchronized in f()");   
  331.               try {   
  332.                   TimeUnit.SECONDS.sleep(3);   
  333.               } catch (InterruptedException e) {   
  334.                   e.printStackTrace();   
  335.               }   
  336.            }   
  337.        } finally {   
  338.            lock1.unlock();   
  339.        }   
  340.     }   
  341.     
  342.     public void g() {   
  343.        // other operations should not be locked...   
  344.        System.out.println(Thread.currentThread().getName()   
  345.               + ":not synchronized in g()");   
  346.        lock2.lock();   
  347.        try {   
  348.            for (int i = 0; i < 5; i++) {   
  349.               System.out.println(Thread.currentThread().getName()   
  350.                      + ":synchronized in g()");   
  351.               try {   
  352.                   TimeUnit.SECONDS.sleep(3);   
  353.               } catch (InterruptedException e) {   
  354.                   e.printStackTrace();   
  355.               }   
  356.            }   
  357.        } finally {   
  358.            lock2.unlock();   
  359.        }   
  360.     }   
  361.     
  362.     public void h() {   
  363.        // other operations should not be locked...   
  364.        System.out.println(Thread.currentThread().getName()   
  365.               + ":not synchronized in h()");   
  366.        lock3.lock();   
  367.        try {   
  368.            for (int i = 0; i < 5; i++) {   
  369.               System.out.println(Thread.currentThread().getName()   
  370.                      + ":synchronized in h()");   
  371.               try {   
  372.                   TimeUnit.SECONDS.sleep(3);   
  373.               } catch (InterruptedException e) {   
  374.                   e.printStackTrace();   
  375.               }   
  376.            }   
  377.        } finally {   
  378.            lock3.unlock();   
  379.        }   
  380.     }   
  381.     
  382.     public static void main(String[] args) {   
  383.        final Resource4 rs = new Resource4();   
  384.     
  385.        new Thread() {   
  386.            public void run() {   
  387.               rs.f();   
  388.            }   
  389.        }.start();   
  390.     
  391.        new Thread() {   
  392.            public void run() {   
  393.               rs.g();   
  394.            }   
  395.        }.start();   
  396.     
  397.        rs.h();   
  398.     }   
  399. }   
  400. 结果:   
  401. Thread-0:not synchronized in f()   
  402. Thread-0:synchronized in f()   
  403. main:not synchronized in h()   
  404. main:synchronized in h()   
  405. Thread-1:not synchronized in g()   
  406. Thread-1:synchronized in g()   
  407. Thread-0:synchronized in f()   
  408. main:synchronized in h()   
  409. Thread-1:synchronized in g()   
  410. Thread-0:synchronized in f()   
  411. main:synchronized in h()   
  412. Thread-1:synchronized in g()   
  413. Thread-0:synchronized in f()   
  414. main:synchronized in h()   
  415. Thread-1:synchronized in g()   
  416. Thread-0:synchronized in f()   
  417. main:synchronized in h()   
  418. Thread-1:synchronized in g()  
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值