采用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对象。
相关推荐
在Java编程中,synchronized和ReentrantLock都是用于实现线程同步的重要工具,它们在并发控制方面扮演着关键角色。然而,两者之间存在一些显著的区别,这些差异体现在功能、灵活性、性能以及使用场景上。 首先,...
本文将深入探讨Synchronized关键字锁和ReentrantLock锁的异同、功能特性以及它们在实际应用中的适用场景。 首先,Synchronized是一种内置的Java关键字,它提供了简单而强大的线程同步机制。当一个线程进入一个由...
在Java多线程编程中,`ReentrantLock`和`synchronized`都是用于实现线程同步的重要工具,确保在并发环境中数据的一致性和正确性。两者虽然都能实现互斥访问,但在功能、性能以及使用场景上有所不同。下面我们将深入...
第15讲丨synchronized和ReentrantLock有什么区别呢?.html
在Java中,有两种主要的锁机制:内置的`synchronized`关键字和显式的`ReentrantLock`类。这两者各有优劣,适用于不同的场景。下面我们将详细讨论它们的区别、性能、特性以及使用上的差异。 1. **功能对比**: - `...
java语言 并发编程 ReentrantLock与synchronized区别 详解
本文将深入探讨四种关键的并发控制机制:synchronized关键字、ReentrantLock(可重入锁)、volatile关键字以及Atomic类的原理与应用。 ### 1. synchronized关键字 `synchronized`关键字是Java提供的内置锁,用于...
Synchronized 的实现是基于锁机制的,它会锁定一个对象的监视器,以便防止其他线程访问该对象。Synchronized 的优点是易于使用和理解,编译器通常会对其进行优化,可以提高性能。然而,Synchronized 也有一些缺点,...
- `ReentrantLock`实现了`Lock`接口,提供了类似`synchronized`的关键字的功能,但提供了更多的灵活性。 - 它支持公平和非公平两种获取锁的策略,默认为非公平锁。 2. **重要特性**: - **可中断等待**:通过`...
在Java并发编程中,理解和熟练...总的来说,Java并发编程中的锁机制是确保线程安全的关键,理解并熟练使用`synchronized`和`ReentrantLock`,以及相应的等待/通知机制,能够帮助开发者设计出高效且可靠的多线程程序。
Java使用synchronized实现互斥锁功能示例 在Java编程语言中,synchronized关键字是实现互斥锁功能的主要手段。互斥锁是一种机制,用于控制多个线程访问共享资源的顺序,从而避免因为资源竞争而导致的程序错误。在...
Java 的并发包 `java.util.concurrent.locks` 提供了其他类型的锁,如 `ReentrantLock`,它提供了更多的控制和调试功能,但相比 `synchronized`,使用时需要更多的手动管理。`ReentrantLock` 也有类似锁升级的过程,...
《深入剖析synchronized锁原理——从Java对象头的角度》 synchronized关键字在Java中扮演着重要的角色,它是Java实现同步的基础,确保了多线程环境下的数据一致性。不同于基于JDK实现的Lock接口(如ReentrantLock)...
除了synchronized,Java并发包`java.util.concurrent.locks`提供了更多的锁实现,如ReentrantLock、ReadWriteLock等,它们提供了更灵活的控制和更高的可定制性,可以根据具体需求选择使用。通过深入学习这些高级锁...
Java并发编程中,`synchronized`关键字和`ReentrantLock`是两个重要的同步控制工具,它们主要用于保证多线程环境下的数据一致性与线程安全。本文将深入探讨这两个概念,了解它们的实现原理以及区别。 首先,`...
背景,应该就是Synchronized的缺点Synchronized产生原因,原子性(Atomicity)与可见性(visibility),其中可见性涉及到JM
本文将深入探讨ReentrantLock的实现原理,包括其与`synchronized`的区别、AQS(AbstractQueuedSynchronizer)的运用,以及lock()和unlock()的实现细节。 1. **synchronized与Lock的对比** - **synchronized的局限...
Java 5引入了`java.util.concurrent.locks.ReentrantLock`,它提供了与`synchronized`相似的功能,但具有更多高级特性,如可中断的等待、公平锁等。在某些情况下,ReentrantLock可能比`synchronized`更适合。 8. *...
与synchronized关键字相比,ReentrantLock提供了更高的灵活性,如尝试加锁、定时加锁和公平锁等功能。本文将深入探讨ReentrantLock的实现原理,主要涉及其内部类AbstractQueuedSynchronizer(AQS)和Unsafe工具类。 ...