java多线程之同步锁(Lock)

Bertha 。 2022-05-17 13:19 489阅读 0赞
  1. Java5开始,提供了Lock Lock提供了比synchronized方法和synchronized代码块更广泛的锁定操作,Lock可以实现更灵活的结构,并且支持多个相关的Condition对象(对象监视器)。
  2. Lock是控制多个线程对共享资源进行访问的工具。通常,锁提供了对共享资源的独占访问,每次只能有一个线程对Lock对象加锁,线程开始访问共享资源之前应先获得Lock对象。

示例代码:

ReentrantLockTest类:

  1. public class ReentrantLockTest {
  2. private final ReentrantLock lock = new ReentrantLock();
  3. //创建10个线程
  4. public void userPrint() {
  5. for (int i = 0; i < 10; i++) {
  6. new Thread(new Runnable() {
  7. public void run() {
  8. print();
  9. }
  10. }).start();
  11. }
  12. }
  13. public void print() {
  14. lock.lock();
  15. System.out.println("线程" + Thread.currentThread().getName() + "正在使用打印机");
  16. try {
  17. Thread.sleep(new Random().nextInt(1000));
  18. System.out.println("线程" + Thread.currentThread().getName() + "资源使用打印机");
  19. } catch (InterruptedException e) {
  20. // TODO Auto-generated catch block
  21. e.printStackTrace();
  22. }
  23. //获取等待得到同步锁的线程个数
  24. System.out.println("还剩 " + lock.getQueueLength() + "人要使用打印机");
  25. lock.unlock();
  26. }
  27. }

Main类:

  1. public class Main {
  2. public static void main(String[] args) throws Exception {
  3. new ReentrantLockTest().userPrint();
  4. }

测试结果:

70

可以看到我们创建的10个线程并没有同时进来使用打印机方法,而是每次至进入一个线程使用打印机。

Lock操作多个Condition对象:

实例代码:

ReentrantLockTest类:

  1. public class ReentrantLockTest {
  2. private final ReentrantLock lock = new ReentrantLock();
  3. private Condition conditionA = lock.newCondition();
  4. private Condition conditionB = lock.newCondition();
  5. public void waitA() {
  6. lock.lock();
  7. try {
  8. System.out.println(Thread.currentThread().getName() + "等待条件");
  9. conditionA.await();
  10. } catch (InterruptedException e) {
  11. // TODO Auto-generated catch block
  12. e.printStackTrace();
  13. }
  14. lock.unlock();
  15. }
  16. public void waitB() {
  17. lock.lock();
  18. try {
  19. System.out.println(Thread.currentThread().getName() + "等待条件(没有人唤醒我,我将一直等待..)");
  20. conditionB.await();
  21. } catch (InterruptedException e) {
  22. // TODO Auto-generated catch block
  23. e.printStackTrace();
  24. }
  25. lock.unlock();
  26. }
  27. public void signal() throws InterruptedException {
  28. lock.lock();
  29. Thread.sleep(1000);
  30. System.out.println(Thread.currentThread().getName() + "执行完毕,唤醒A");
  31. conditionA.signal();
  32. lock.unlock();
  33. }
  34. public void condition() throws InterruptedException {
  35. new Thread(new Runnable() {
  36. public void run() {
  37. waitA();
  38. }
  39. }).start();
  40. new Thread(new Runnable() {
  41. public void run() {
  42. waitB();
  43. }
  44. }).start();
  45. new Thread(new Runnable() {
  46. public void run() {
  47. try {
  48. signal();
  49. } catch (InterruptedException e) {
  50. // TODO Auto-generated catch block
  51. e.printStackTrace();
  52. }
  53. }
  54. }).start();
  55. }
  56. }

Mian类:

  1. public class Main {
  2. public static void main(String[] args) throws Exception {
  3. new ReentrantLockTest().condition();
  4. }

测试结果:

70 1

上例中,我们可以看到我们创建了两个Condition对象,并且启动了三个线程,waitA和waitB方法都在其中一个线程执行,但是signal方法只唤醒了持有ConditionA的方法,而另一个waitB方法将一直等待被唤醒。使用Condition可以进行线程间的通信。

发表评论

表情:
评论列表 (有 0 条评论,489人围观)

还没有评论,来说两句吧...

相关阅读

    相关 线同步 lock

    ock是一个接口,是通过代码来实现的,他的底层也是基于CAS原理,属于一种乐观锁,他与synchronized也有一定的区别: 1.用法不一样。synchronized...