JUC学习(一):synchronized的介绍及使用(实现多线程卖票)

简介: JUC学习(一):synchronized的介绍及使用(实现多线程卖票)

一、synchronized简介



synchronized 是 Java 中的关键字,是一种同步锁。它修饰的对象有以下几种:


1、修饰一个代码块,被修饰的代码块称为同步语句块,其作用的范围是大括号{} 括起来的代码,作用的对象是调用这个代码块的对象;

2、修饰一个方法,被修饰的方法称为同步方法,其作用的范围是整个方法,作用的对象是调用这个方法的对象;

3、修改一个静态的方法,其作用的范围是整个静态方法,作用的对象是这个类的所有对象;         4、修改一个类,其作用的范围是 synchronized 后面括号括起来的部分,作用主的对象是这个类的所有对象。


注意:虽然可以使用 synchronized 来定义方法,但 synchronized 并不属于方法定义的一部分,因此,synchronized 关键字不能被继承。如果在父类中的某个方法使用了 synchronized 关键字,而在子类中覆盖了这个方法,在子类中的这个方法默认情况下并不是同步的,而必须显式地在子类的这个方法中加上synchronized 关键字才可以。当然,还可以在子类方法中调用父类中相应的方法,这样虽然子类中的方法不是同步的,但子类调用了父类的同步方法,因此,子类的方法也就相当于同步了。


二、synchronized的简单使用:多人售票案例



本例实现3个人卖30张票

/**
 * synchronized练习,3个人卖30张票
 */
//第一步:创建资源类,定义属性和操作方法
class Ticket{
    //票的数量
    private int number = 30;
    //卖票方法
    public synchronized void sale(){
        if (number > 0){
            System.out.println(Thread.currentThread().getName() + "卖出票,还剩" + --number + "张票");
        }
    }
}
public class SaleTicket {
    //第二步,创建多个线程,调用资源类中的操作方法
    public static void main(String[] args) {
        Ticket ticket = new Ticket();
        //线程1
        new Thread(new Runnable() {
            @Override
            public void run() {
                for(int i=0; i<40; i++){
                    //卖票
                    ticket.sale();
                    try {
                        Thread.sleep(10);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }
        }, "售票员A").start();
        //线程2
        new Thread(new Runnable() {
            @Override
            public void run() {
                for (int i = 0; i < 40; i++) {
                    //卖票
                    ticket.sale();
                    try {
                        Thread.sleep(10);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }
        }, "售票员B").start();
        //线程3
        new Thread(new Runnable() {
            @Override
            public void run() {
                for (int i = 0; i < 40; i++) {
                    //卖票
                    ticket.sale();
                    try {
                        Thread.sleep(10);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }
        }, "售票员C").start();
    }
}



运行结果:

售票员A卖出票,还剩29张票
售票员B卖出票,还剩28张票
售票员C卖出票,还剩27张票
售票员B卖出票,还剩26张票
售票员C卖出票,还剩25张票
售票员A卖出票,还剩24张票
售票员C卖出票,还剩23张票
售票员B卖出票,还剩22张票
售票员A卖出票,还剩21张票
售票员C卖出票,还剩20张票
售票员B卖出票,还剩19张票
售票员A卖出票,还剩18张票
售票员C卖出票,还剩17张票
售票员B卖出票,还剩16张票
售票员A卖出票,还剩15张票
售票员C卖出票,还剩14张票
售票员B卖出票,还剩13张票
售票员A卖出票,还剩12张票
售票员C卖出票,还剩11张票
售票员B卖出票,还剩10张票
售票员A卖出票,还剩9张票
售票员C卖出票,还剩8张票
售票员B卖出票,还剩7张票
售票员A卖出票,还剩6张票
售票员C卖出票,还剩5张票
售票员A卖出票,还剩4张票
售票员B卖出票,还剩3张票
售票员C卖出票,还剩2张票
售票员B卖出票,还剩1张票
售票员A卖出票,还剩0张票





相关文章
|
2月前
|
Java 调度 C#
C#学习系列相关之多线程(一)----常用多线程方法总结
C#学习系列相关之多线程(一)----常用多线程方法总结
|
2月前
|
安全 编译器 C#
C#学习相关系列之多线程---lock线程锁的用法
C#学习相关系列之多线程---lock线程锁的用法
|
2月前
|
C#
C#学习相关系列之多线程---ConfigureAwait的用法
C#学习相关系列之多线程---ConfigureAwait的用法
|
3天前
|
消息中间件 缓存 Java
【多线程学习】深入探究定时器的重点和应用场景
【多线程学习】深入探究定时器的重点和应用场景
|
3天前
|
监控 安全 Java
【多线程学习】深入探究阻塞队列与生产者消费者模型和线程池常见面试题
【多线程学习】深入探究阻塞队列与生产者消费者模型和线程池常见面试题
|
3天前
|
消息中间件 监控 安全
【JAVAEE学习】探究Java中多线程的使用和重点及考点
【JAVAEE学习】探究Java中多线程的使用和重点及考点
|
9天前
|
并行计算 算法 安全
Java从入门到精通:2.1.3深入学习Java核心技术——掌握Java多线程编程
Java从入门到精通:2.1.3深入学习Java核心技术——掌握Java多线程编程
|
20天前
|
存储 安全 Java
多线程编程常见面试题讲解(锁策略,CAS策略,synchronized原理,JUC组件,集合类)(下)
多线程编程常见面试题讲解(锁策略,CAS策略,synchronized原理,JUC组件,集合类)(下)
43 0
|
20天前
|
存储 安全 Java
多线程编程常见面试题讲解(锁策略,CAS策略,synchronized原理,JUC组件,集合类)(上)
多线程编程常见面试题讲解(锁策略,CAS策略,synchronized原理,JUC组件,集合类)
35 0
|
25天前
|
C++
C++语言多线程学习应用案例
使用C++ `std::thread`和`std::mutex`实现多线程同步。示例创建两个线程`t1`、`t2`,共享资源`shared_resource`,每个线程调用`increase`函数递增资源值。互斥锁确保在任何时候只有一个线程访问资源,防止数据竞争。最后输出资源总值。
9 1