关于火车票案例中 synchronized放在代码哪里的解释:
案例1: 火车票案例
特点: 多窗口下执行的同一个操作动作,使用的同一个公共数据,使用同一个runnable对象
package thread; public class RunnableInUse { /** * 1 业务类传递给 runnable类 runbanle类传递给 thread类 * 2 如果要执行方法是同一个业务方法,那么只需要创建一个runnable类,在这个类里面调动这个业务类的业务方法即可 * 3 如果要执行方法是不同业务方法,那么需要根据业务方法的不同和实际需要来创建对应个数的runnable类,后在thread类里调用不同的runnble类 */ public static void main(String[] args) { MyTicket myTicket = new MyTicket(); new Thread(new MyRunnable1(myTicket)).start(); new Thread(new MyRunnable1(myTicket)).start(); } } class MyRunnable1 implements Runnable{ private MyTicket myTicket; public MyRunnable1(MyTicket myTicket){ this.myTicket = myTicket; } @Override public void run() { myTicket.sellTicket(); } } // 业务方法都要封装在业务类中,方法上加锁 class MyTicket { private int ticketNum = 100; public void sellTicket(){ // 需要在方法内加锁,如果在方法头上加锁,第一个线程进来后直到执行完才能轮到第二个线程,这样就和多窗口买票违背了 while(ticketNum > 1) { synchronized (this) { ticketNum--; System.out.println("出票口" + Thread.currentThread().getName() + "卖票成功,还剩下 " + ticketNum + "个票"); } } } /** * 执行结果: * 出票口Thread-0卖票成功,还剩下 92个票 出票口Thread-0卖票成功,还剩下 91个票 出票口Thread-0卖票成功,还剩下 90个票 出票口Thread-0卖票成功,还剩下 89个票 出票口Thread-0卖票成功,还剩下 88个票 出票口Thread-0卖票成功,还剩下 87个票 出票口Thread-0卖票成功,还剩下 86个票 出票口Thread-0卖票成功,还剩下 85个票 出票口Thread-0卖票成功,还剩下 84个票 出票口Thread-0卖票成功,还剩下 83个票 出票口Thread-0卖票成功,还剩下 82个票 出票口Thread-0卖票成功,还剩下 81个票 出票口Thread-0卖票成功,还剩下 80个票 出票口Thread-0卖票成功,还剩下 79个票 出票口Thread-0卖票成功,还剩下 78个票 出票口Thread-0卖票成功,还剩下 77个票 出票口Thread-0卖票成功,还剩下 76个票 出票口Thread-0卖票成功,还剩下 75个票 出票口Thread-1卖票成功,还剩下 74个票 出票口Thread-1卖票成功,还剩下 73个票 出票口Thread-1卖票成功,还剩下 72个票 出票口Thread-1卖票成功,还剩下 71个票 出票口Thread-1卖票成功,还剩下 70个票 出票口Thread-1卖票成功,还剩下 69个票 */ }
案例2: 设计4个线程,其中两个每次对j加1, 另外两个每次对j减1
特点: 多个线程执行的方法不同,此时需要不同的runnable对象,但是又需要共享同一个数据
总结: 可以用如下方式来实现:
1 将共享数据封装在另一对象中,将这个对象传递给各个runnable对象,
2 线程对共享数据的操作需要分配到这个对象上来完成,对象上的方法增加同步锁,因为所有线程使用同一个对象,因此锁栓一致。
代码:
package thread; public class RunnableInUser2 { /** * 两个线程对变量递增 * 两个线程对变量递减 */ public static void main(String[] args) { AddAndDelete addAndDelete = new AddAndDelete(); for(int i=0; i<4;i++){ new Thread(new AddRunnable(addAndDelete)).start(); new Thread(new DeleteRunnable(addAndDelete)).start(); } } } class AddRunnable implements Runnable{ private AddAndDelete addAndDelete; public AddRunnable(AddAndDelete addAndDelete){ this.addAndDelete = addAndDelete; } @Override public void run() { addAndDelete.addOne(); } } class DeleteRunnable implements Runnable{ private AddAndDelete addAndDelete; public DeleteRunnable(AddAndDelete addAndDelete){ this.addAndDelete = addAndDelete; } @Override public void run() { addAndDelete.deleteOne(); } } class AddAndDelete{ private int num = 0; public synchronized void addOne(){ System.out.println("addOne, the result is" + num++); } public synchronized void deleteOne(){ System.out.println("deleteOne, the result is" + num--); } /** * addOne, the result is0 deleteOne, the result is1 addOne, the result is0 deleteOne, the result is1 addOne, the result is0 deleteOne, the result is1 addOne, the result is0 deleteOne, the result is1 */ }
脑图:
相关推荐
本示例“简单实现多线程同步示例(模拟购票系统)”旨在通过一个具体的实例,帮助开发者理解如何在Java中创建并管理多线程以及如何实现线程同步,确保数据的一致性和正确性。 首先,我们要明确多线程的基本概念。在...
在Java编程中,多线程...总的来说,模拟多人不同面值购票找零的多线程代码需要深入理解和运用Java的多线程机制、同步控制以及异常处理。通过合理的线程设计和数据同步,我们可以构建出一个高效、安全的购票找零系统。
这个文件可能包含了购票操作的核心逻辑,比如定义了一个`SaleTicket`类,它可能包含了一个共享资源(票的数量)和多线程安全的购票方法。购票操作通常需要进行同步控制,防止多个线程同时修改票的数量,导致数据不...
"多线程设计一个火车售票模拟程序" ...我们了解了多线程设计的重要性,并学习了如何使用 synchronized 关键字来实现线程同步。这个程序可以作为一个简单的示例,展示了多线程技术在实际应用中的重要性。
1. **多线程的创建**:Java支持通过继承`Thread`类或实现`Runnable`接口两种方式创建多线程。 2. **同步技术**:Java通过`synchronized`关键字提供同步机制,确保多个线程在访问共享资源时不会发生冲突。 3. **流程...
- **1.3**:Java内置多线程支持,简化了编程模型,如使用 `synchronized`, `volatile` 等关键字处理并发问题。 **3. 线程在内存中的状态** 线程有多种状态,如新建、可运行、运行、阻塞、等待、终止等。在JVM内存中...
在本项目"一个多线程模拟购票系统"中,我们将深入探讨如何利用Java的多线程特性来设计和实现一个能够模拟实际售票过程的系统。这个系统的核心目标是确保在高并发环境下,票务资源的正确管理和分配。 首先,我们要...
在我们的例子中,"4窗口同时买票"就是一种多线程的体现,每个售票窗口可以看作一个独立运行的线程,它们可以同时为不同的客户办理购票业务,提高工作效率。 多线程在实际应用中有着广泛的应用,例如在服务器端处理...
创建多线程的方式多种多样,比如在Java中,可以使用`Thread`类的子类或者实现`Runnable`接口来创建线程。在Python中,可以使用`threading`模块的`Thread`类。在创建线程后,通常需要调用`start()`方法启动线程,这样...
在多线程环境下,竞态条件是指当两个或更多线程可以同时修改同一数据时,其最终结果取决于线程的调度,可能导致不一致的结果。为避免竞态条件,可以使用以下同步机制: 1. **互斥锁**:只允许一个线程访问共享资源...
线程同步机制是为了避免在多线程环境下出现数据不一致或资源竞争问题,如死锁、活锁和饥饿等。Java提供了多种同步机制,如synchronized关键字、Lock接口(包括ReentrantLock)、Semaphore信号量、Condition条件变量...
总结起来,Java多线程同步是通过`synchronized`关键字实现的,它可以应用于方法或代码块,保证同一时刻只有一个线程能够执行特定的代码。通过合理使用同步机制,开发者可以有效地管理并发程序中的资源访问,避免数据...
- 多线程并发提高了程序执行效率,例如在购票场景中,不同窗口可以同时为不同客户提供服务。 3. **实现多线程的条件**: - **多核CPU**能真正实现多线程并发,每个核心可以同时处理一个线程。 - **单核CPU**通过...
在Java编程语言中,多线程是其一个重要的高级特性,它使得程序可以在同一时间执行多个不同的任务,从而提高了程序的效率和响应性。在这个"Java高级特性 - 多线程练习题.zip"中,我们可以看到两个文件,分别是"顺序...
通过实际的案例,如多线程模拟猴子采花、使用同步方法模拟购票、多线程模拟购物订单生成以及使用`ThreadLocal`模拟银行取款等,我们可以深入理解并实践这些多线程编程的概念和技术,从而更好地应对并发编程的挑战。
其次,Java的多线程可以通过继承`Thread`类或实现`Runnable`接口来实现。实验中的`SimpleThread`类继承了`Thread`,重写了`run()`方法,这是线程执行的主要逻辑。在`main`方法中,创建了两个`SimpleThread`实例并...
该系统主要用于演示如何在Java中使用多线程技术来处理并发访问资源的问题,并展示了线程同步的重要性。 #### 核心知识点 1. **多线程基础** - 在Java中,多线程是指在运行时能够同时执行多个任务的能力。 - Java...
在多线程编程中,可能会用到一些设计模式,如生产者消费者模型(使用`BlockingQueue`)、单例模式(确保类只有一个实例,尤其在多线程环境下的安全性)等。 这个基于Java多线程同步技术的简易模拟售票系统,不仅...
在Java中,多线程是通过`Thread`类或者实现`Runnable`接口来创建的。线程是程序执行的最小单位,每个线程都有自己的执行路径,可以同时处理不同的任务。在并发售票系统中,每个购票请求都可以视为一个独立的线程。 ...