Java复习与学习笔记----进程和线程与同步(下)

简介: Java复习与学习笔记----进程和线程与同步(下)

案例–买票

在实现Runnable接口的类中,获取当前类线程的名字:Thread.currentThread().getName()

public class SellTickket implements Runnable {
    private int ticket = 100;
    @Override
    public void run() {
        while ( true ) {
            if ( ticket>0 ) {
                System.out.println( Thread.currentThread().getName()+"正在出售第"+ticket+"张票" );
                ticket--;
            }
        }
    }
}
public class Test {
    public static void main(String[] args) {
        SellTickket sellTickket = new SellTickket();
        Thread t1 = new Thread(sellTickket, "窗口1");
        Thread t2 = new Thread(sellTickket, "窗口2");
        Thread t3 = new Thread(sellTickket, "窗口3");
        t1.start();
        t2.start();
        t3.start();
    }
}

买票出现的问题:

1.相同的票出现了多次

2.出现负数的票

出现问题的原因:

线程执行的随机性导致

解决多线程导致的问题

为什么出现问题:

这也是判断多线程程序是否会有数据安全问题的标准

1.是否为多线程环境

2.是否共享数据

3.是否有多条语句操作共享数据

如何解决多线程安全问题:

基本思想:让程序没有安全问题的环境

如何实现:把多条语句操作共享数据的代码锁起来,让任意时刻只有一个线程执行即可,Java提供了同步代码块的方式来解决

同步代码块

锁多条语句操作共享数据,可以使用同步代码块实现

格式:

synchronized ( 任意对象 ) {
    多条语句操作共享数据的代码
}

synchronized ( 任意对象 ) :就相当于给代码加锁,任意对象可以看出一把锁

public class SellTickket implements Runnable {
    private int ticket = 100;
    private Object obj = new Object();
    @Override
    public void run() {
        while (true) {
            synchronized (obj) {
                if (ticket > 0) {
                    System.out.println(Thread.currentThread().getName() + "正在出售第" + ticket + "张票");
                    ticket--;
                }
            }
        }
    }
}

同步锁中的对象,必须所有线程是同一个对象,否则每个线程会各自有一把锁,无法解决多线程导致的问题

同步的好处与弊端:

好处:解决了多线程的数据安全问题

弊端:当线程很多时,因为每个线程都会去判断同步上的锁,很耗费资源,会降低程序的运行效率

同步方法

同步方法:

就是把synchronized关键字加到方法上

格式:

修饰符 synchronized 返回值类型 方法名( 方法参数 ) {   }
• 1
public synchronized void sellTicket() {
        if (ticket > 0) {
            try {
                Thread.sleep(100);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println(Thread.currentThread().getName() + "正在出售第" + ticket + "张票");
            ticket--;
        }
    }

同步方法中的锁对象是 this

同步静态方法

就是把synchronized关键字加到静态方法上

格式

修饰符 static synchronized 返回值类型 方法名( 方法参数 ) {   }

同步静态方法的锁对象是 类名.class

线程安全的类

Collections中存在方法可以将线程不同步的转化为线程同步

Collections.synchronizedList();
Collections.synchronizedMap();
Collections.synchronizedSet();
......

Lock锁

Lock中提供了获得锁和释放所的方法,使用该方法比synchronized更加直观

void lock ()  获得锁
void unlock ()  释放锁

Lock是接口,不能直接实例化,采用Lock的实现类ReentrantLock实例化一个对象

Lock lock = new ReentrantLock();
//需要加锁的代码块前一行加上
lock.lock();
//加锁的代码块执行结束释放锁
lock.unlock();
//为了保证线程的锁一定会释放
            //会把释放锁放在finally中
            try {
                lock.lock();
                if (ticket > 0) {
                    try {
                        Thread.sleep(100);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    System.out.println(Thread.currentThread().getName() + "正在出售第" + ticket + "张票");
                    ticket--;
                }
            } finally {
                lock.unlock();
            }

生产者消费者


相关文章
|
9月前
|
Java API 微服务
2025 年 Java 从入门到精通学习笔记全新版
《Java学习笔记:从入门到精通(2025更新版)》是一本全面覆盖Java开发核心技能的指南,适合零基础到高级开发者。内容包括Java基础(如开发环境配置、核心语法增强)、面向对象编程(密封类、接口增强)、进阶技术(虚拟线程、结构化并发、向量API)、实用类库与框架(HTTP客户端、Spring Boot)、微服务与云原生(容器化、Kubernetes)、响应式编程(Reactor、WebFlux)、函数式编程(Stream API)、测试技术(JUnit 5、Mockito)、数据持久化(JPA、R2DBC)以及实战项目(Todo应用)。
492 5
|
8月前
|
安全 算法 Java
Java 多线程:线程安全与同步控制的深度解析
本文介绍了 Java 多线程开发的关键技术,涵盖线程的创建与启动、线程安全问题及其解决方案,包括 synchronized 关键字、原子类和线程间通信机制。通过示例代码讲解了多线程编程中的常见问题与优化方法,帮助开发者提升程序性能与稳定性。
366 0
|
12月前
|
存储 Java
# 【Java全栈学习笔记-U1-day02】变量+数据类型+运算符
本篇笔记主要围绕Java全栈学习的第二天内容展开,涵盖了变量、数据类型、运算符以及Scanner类的应用。首先介绍了变量的概念与命名规范,以及如何定义和使用变量;接着详细讲解了Java中的基本数据类型,包括整型、浮点型、字符型、布尔型等,并通过实例演示了数据类型的运用。随后,深入探讨了各类运算符(赋值、算术、关系、逻辑)及其优先级,帮助理解表达式的构成。最后,介绍了如何利用Scanner类实现用户输入功能,并通过多个综合示例(如计算圆面积、购物打折、变量交换及银行利息计算)巩固所学知识。完成相关作业将进一步加深对这些基础概念的理解与实践能力。
233 13
|
5月前
|
JSON 网络协议 安全
【Java】(10)进程与线程的关系、Tread类;讲解基本线程安全、网络编程内容;JSON序列化与反序列化
几乎所有的操作系统都支持进程的概念,进程是处于运行过程中的程序,并且具有一定的独立功能,进程是系统进行资源分配和调度的一个独立单位一般而言,进程包含如下三个特征。独立性动态性并发性。
290 1
|
5月前
|
JSON 网络协议 安全
【Java基础】(1)进程与线程的关系、Tread类;讲解基本线程安全、网络编程内容;JSON序列化与反序列化
几乎所有的操作系统都支持进程的概念,进程是处于运行过程中的程序,并且具有一定的独立功能,进程是系统进行资源分配和调度的一个独立单位一般而言,进程包含如下三个特征。独立性动态性并发性。
310 1
|
6月前
|
小程序 Java 知识图谱
Java 学习笔记 —— BMI & BMR 计算器
这是一个使用 Java 编写的 BMI 与 BMR 计算器小程序,可输入年龄、性别、身高和体重,计算身体质量指数(BMI)和基础代谢率(BMR),并输出健康评估结果。通过该项目,掌握了 Java 的输入处理、数据验证、条件判断、数学运算及格式化输出等基础知识,是 Java 初学者的理想练习项目。
|
6月前
|
Java
Java 数组学习笔记
本文整理Java数组常用操作:遍历、求和、查找、最值及二维数组行求和等典型练习,涵盖静态初始化、元素翻倍、去极值求平均等实例,帮助掌握数组基础与应用。
|
开发框架 Java 开发工具
【Java全栈学习笔记-U1-day01】Java介绍
本笔记整理了Java学习的基础内容,涵盖程序理解、Java语言特性、JDK安装与配置、Java程序开发工具及编写步骤。重点介绍了Java程序的基本结构、编译和运行过程,以及输出语句的使用。通过实例演示了IDEA创建Java程序的方法,并强调了编码规范和注意事项。适合初学者复习和交流学习。 主要内容: 1. 理解程序:计算机组成、程序定义。 2. 简介:Java语言特点、技术平台、JDK作用。 3. 编写Java程序:编写、编译、运行步骤,基本结构。 4. 输出语句 5. DEA使用:新建工程、保存位置、文件介绍、新建类。 6. 扩展:注释、代码规范、大小写敏感、缩进等。
|
Java 对象存储 开发者
如何找出Java进程占用CPU高的元凶
本文记录了一次Java进程CPU占用率过高的问题和排查思路。
|
Java 数据库连接 API
Spring 框架的介绍(Java EE 学习笔记02)
Spring是一个由Rod Johnson开发的轻量级Java SE/EE一站式开源框架,旨在解决Java EE应用中的多种问题。它采用非侵入式设计,通过IoC和AOP技术简化了Java应用的开发流程,降低了组件间的耦合度,支持事务管理和多种框架的无缝集成,极大提升了开发效率和代码质量。Spring 5引入了响应式编程等新特性,进一步增强了框架的功能性和灵活性。

热门文章

最新文章