`
wuliHjz123
  • 浏览: 5325 次
  • 性别: Icon_minigender_1
  • 来自: 武汉
社区版块
存档分类
最新评论

关于synchronized和ReentrantLock实现卖票功能以及synchronized的对象锁和全局锁验证

阅读更多

采用synchronize关键字实现卖票
package com.huang.thread;

/**
 * 卖票
 * 使用synchronize关键字实现
 * @author 黄
 *
 */
public class TicketSynch implements Runnable {

 private int ticketCount;
 
 public TicketSynch(int ticketCount) {
  this.ticketCount = ticketCount;
 }
 
 public void sell() {
  while(true) {
   synchronized (this) {
    if(ticketCount > 0) {
     try {
      //模拟买票的动作
      Thread.sleep(100);
     } catch (InterruptedException e) {
      e.printStackTrace();
     }
     ticketCount --;
     System.out.println(Thread.currentThread().getName() + "卖出一张票:剩余票数" + ticketCount);
    }else {
     System.exit(0);
    }
   }
  }
 }
 
 @Override
 public void run() {
  sell();
  
 }

}


采用Reentrantlock关键字实现卖票

package com.huang.thread;

import java.util.concurrent.locks.ReentrantLock;

/**
 * 卖票
 * 使用Reentrantlock 重入锁控制
 * @author 黄
 *
 */
public class TicketLock implements Runnable {
 
 private int ticketCount;
 
 private ReentrantLock lock = new ReentrantLock();
 
 public TicketLock(int ticketCount) {
  this.ticketCount = ticketCount;
 }
 
 public void sell() {
  while(true) {
   try {
    lock.lock();
    if(ticketCount > 0) {
     try {
      //模拟买票的动作
      Thread.sleep(100);
     } catch (InterruptedException e) {
      e.printStackTrace();
     }
     ticketCount --;
     System.out.println(Thread.currentThread().getName() + "卖出一张票:剩余票数" + ticketCount);
    }else {
     System.exit(0);
    }
   }catch (Exception e) {
    e.printStackTrace();
   }finally {
    lock.unlock();
   }
  }
 }
 
 @Override
 public void run() {
  sell();
 }

}

 

测试类

package com.huang.thread;

import org.junit.jupiter.api.Test;

public class TestTicket {
 
 @Test
 public void testSynch() {
  TicketSynch ticketSynch = new TicketSynch(100);
  //这里调用synchronized (this)同步锁对象的方法。这里输出的对象和this是同一个对象
  //System.out.println(ticketSynch);
  
  new Thread(ticketSynch,"窗口1").start();
  new Thread(ticketSynch,"窗口2").start();
  new Thread(ticketSynch,"窗口3").start();
  new Thread(ticketSynch,"窗口4").start();
  new Thread(ticketSynch,"窗口5").start();
  
  try {
   //主线程等到30秒,等待其他线程执行完成
   Thread.sleep(30*1000);
  } catch (InterruptedException e) {
   e.printStackTrace();
  }
 }
 
 @Test
 public void testLock() {
  TicketLock ticketSynch = new TicketLock(100);
  
  new Thread(ticketSynch,"窗口1").start();
  new Thread(ticketSynch,"窗口2").start();
  new Thread(ticketSynch,"窗口3").start();
  new Thread(ticketSynch,"窗口4").start();
  new Thread(ticketSynch,"窗口5").start();
  
  try {
   //主线程等到30秒,等待其他线程执行完成
   Thread.sleep(30*1000);
  } catch (InterruptedException e) {
   e.printStackTrace();
  }
 }
 
 /**
  * 测试Synchronize关键字的全局锁和对象锁
  */
 @Test
 public void testSynchLock() {
  TicketSynchLock ticketSynch = new TicketSynchLock();
  new Thread(ticketSynch,"窗口1").start();
  new Thread(ticketSynch,"窗口2").start();
  new Thread(ticketSynch,"窗口3").start();
  TicketSynchLock ticketSynch1 = new TicketSynchLock();
  new Thread(ticketSynch1,"窗口3").start();
  new Thread(ticketSynch1,"窗口4").start();
  
  try {
   //主线程等到30秒,等待其他线程执行完成
   Thread.sleep(30*1000);
  } catch (InterruptedException e) {
   e.printStackTrace();
  }
 }

}

synchronized的对象锁和全局锁验证,重新写一下类

package com.huang.thread;

/**
 * 卖票
 * 使用synchronize关键字实现
 * @author 黄
 *
 */
public class TicketSynchLock implements Runnable {

 private static int ticketCount = 100;
 
 /**
  * 对象锁
  */
 public void sell() {
  while(true) {
   synchronized (this) {
    if(ticketCount > 0) {
     try {
      //模拟买票的动作
      Thread.sleep(100);
     } catch (InterruptedException e) {
      e.printStackTrace();
     }
     ticketCount --;
     System.out.println(Thread.currentThread().getName() + "卖出一张票:剩余票数" + ticketCount);
    }else {
     return;
    }
   }
  }
 }
 
 /**
  * 全局锁
  */
 public void sell1() {
  while(true) {
   synchronized (TicketSynchLock.class) {
    if(ticketCount > 0) {
     try {
      //模拟买票的动作
      Thread.sleep(100);
     } catch (InterruptedException e) {
      e.printStackTrace();
     }
     ticketCount --;
     System.out.println(Thread.currentThread().getName() + "卖出一张票:剩余票数" + ticketCount);
    }else {
     return;
    }
   }
  }
 }
 
 @Override
 public void run() {
  //sell();
  sell1();
  
 }

}


测试,上面测试类的testSynchLock()方法,当TicketSynchLock类run方法执行的是sell()的时候,则会出现-1张票,如果执行sell1(),则不会

借鉴网上博客的描述:

synchronized 作用在普通方法上属于对象锁,作用在静态方法,类.class 上面,属于全局锁。对象锁只对同一个对象加锁,作用对象是同一个对象。而类锁是对类加锁,对整个类都有效。
如果锁住的是一般方法就是对象锁,对象锁只会对同一个对象起作用,如果是锁住了static 方法则是全局锁,会对全局对象都管用,如果想在普通方法中使用全局锁需要锁住class对象。

 

 

分享到:
评论

相关推荐

    第15讲 synchronized和ReentrantLock有什么区别呢?1

    在Java编程中,synchronized和ReentrantLock都是用于实现线程同步的重要工具,它们在并发控制方面扮演着关键角色。然而,两者之间存在一些显著的区别,这些差异体现在功能、灵活性、性能以及使用场景上。 首先,...

    简单聊聊Synchronized和ReentrantLock锁.docx

    本文将深入探讨Synchronized关键字锁和ReentrantLock锁的异同、功能特性以及它们在实际应用中的适用场景。 首先,Synchronized是一种内置的Java关键字,它提供了简单而强大的线程同步机制。当一个线程进入一个由...

    ReentrantLock与synchronized

    在Java多线程编程中,`ReentrantLock`和`synchronized`都是用于实现线程同步的重要工具,确保在并发环境中数据的一致性和正确性。两者虽然都能实现互斥访问,但在功能、性能以及使用场景上有所不同。下面我们将深入...

    第15讲丨synchronized和ReentrantLock有什么区别呢?.html

    第15讲丨synchronized和ReentrantLock有什么区别呢?.html

    22 到底哪把锁更适合你?—synchronized与ReentrantLock对比.pdf

    在Java中,有两种主要的锁机制:内置的`synchronized`关键字和显式的`ReentrantLock`类。这两者各有优劣,适用于不同的场景。下面我们将详细讨论它们的区别、性能、特性以及使用上的差异。 1. **功能对比**: - `...

    ReentrantLock与synchronized区别

    java语言 并发编程 ReentrantLock与synchronized区别 详解

    synchronized ReentrantLock volatile Atomic 原理分析.docx

    本文将深入探讨四种关键的并发控制机制:synchronized关键字、ReentrantLock(可重入锁)、volatile关键字以及Atomic类的原理与应用。 ### 1. synchronized关键字 `synchronized`关键字是Java提供的内置锁,用于...

    Lock、Synchoronized和ReentrantLock的使用

    Synchronized 的实现是基于锁机制的,它会锁定一个对象的监视器,以便防止其他线程访问该对象。Synchronized 的优点是易于使用和理解,编译器通常会对其进行优化,可以提高性能。然而,Synchronized 也有一些缺点,...

    ReentrantLock 与 synchronized 简介

    - `ReentrantLock`实现了`Lock`接口,提供了类似`synchronized`的关键字的功能,但提供了更多的灵活性。 - 它支持公平和非公平两种获取锁的策略,默认为非公平锁。 2. **重要特性**: - **可中断等待**:通过`...

    深入java并发编程,使用ReentrantLock和 Synchronized加锁

    在Java并发编程中,理解和熟练...总的来说,Java并发编程中的锁机制是确保线程安全的关键,理解并熟练使用`synchronized`和`ReentrantLock`,以及相应的等待/通知机制,能够帮助开发者设计出高效且可靠的多线程程序。

    Java使用synchronized实现互斥锁功能示例

    Java使用synchronized实现互斥锁功能示例 在Java编程语言中,synchronized关键字是实现互斥锁功能的主要手段。互斥锁是一种机制,用于控制多个线程访问共享资源的顺序,从而避免因为资源竞争而导致的程序错误。在...

    第16讲 synchronized底层如何实现?什么是锁的升级、降级?1

    Java 的并发包 `java.util.concurrent.locks` 提供了其他类型的锁,如 `ReentrantLock`,它提供了更多的控制和调试功能,但相比 `synchronized`,使用时需要更多的手动管理。`ReentrantLock` 也有类似锁升级的过程,...

    synchronized锁原理分析(一、从Java对象头看synchronized锁的状态)

    《深入剖析synchronized锁原理——从Java对象头的角度》 synchronized关键字在Java中扮演着重要的角色,它是Java实现同步的基础,确保了多线程环境下的数据一致性。不同于基于JDK实现的Lock接口(如ReentrantLock)...

    第16讲synchronized底层如何实现?什么是锁...1

    除了synchronized,Java并发包`java.util.concurrent.locks`提供了更多的锁实现,如ReentrantLock、ReadWriteLock等,它们提供了更灵活的控制和更高的可定制性,可以根据具体需求选择使用。通过深入学习这些高级锁...

    Java实习生面试复习(七):synchronized和ReentrantLock的学习

    Java并发编程中,`synchronized`关键字和`ReentrantLock`是两个重要的同步控制工具,它们主要用于保证多线程环境下的数据一致性与线程安全。本文将深入探讨这两个概念,了解它们的实现原理以及区别。 首先,`...

    wangwang4git#just-do#简单说说Synchronized,ReentrantLock1

    背景,应该就是Synchronized的缺点Synchronized产生原因,原子性(Atomicity)与可见性(visibility),其中可见性涉及到JM

    ReentrantLock实现原理详解

    本文将深入探讨ReentrantLock的实现原理,包括其与`synchronized`的区别、AQS(AbstractQueuedSynchronizer)的运用,以及lock()和unlock()的实现细节。 1. **synchronized与Lock的对比** - **synchronized的局限...

    synchronized关键字的实质及用法

    Java 5引入了`java.util.concurrent.locks.ReentrantLock`,它提供了与`synchronized`相似的功能,但具有更多高级特性,如可中断的等待、公平锁等。在某些情况下,ReentrantLock可能比`synchronized`更适合。 8. *...

    ReentrantLock解析

    与synchronized关键字相比,ReentrantLock提供了更高的灵活性,如尝试加锁、定时加锁和公平锁等功能。本文将深入探讨ReentrantLock的实现原理,主要涉及其内部类AbstractQueuedSynchronizer(AQS)和Unsafe工具类。 ...

Global site tag (gtag.js) - Google Analytics