一、同步代码块

package com.synchronized1;

// 买票示例
// 使用同步代码块解决线程安全问题
public class TicketRunnableImp implements Runnable {
private int ticket = 100;
Object o=new Object();
@Override
public void run() {
while (true) {
synchronized (o){
if (ticket > 0) {
System.out.println(Thread.currentThread().getName() + "-->正在售第"+ticket+"张票!");
ticket--;
}
}
}
}
}
实现原理:使用了一个锁对象.这个锁对象也叫同步锁,对象锁,对象监视器。先进入同步代码块的线程会先获取到锁对象,其他线程不能进入代码块,只有先进入同步代码块的线程
执行完毕同步代码块释放锁对象后,其他线程才有机会获取到锁对象进入同步代码块。也就是每次只有一个线程进入到同步代码块执行逻辑。

优点:实现了线程安全
缺点:程序不停的判断锁,获取锁,释放锁,效率会降低

二、同步方法

package com.synchronized2;

// 买票示例
// 使用同步方法解决线程安全问题
public class TicketRunnableImp implements Runnable {
private int ticket = 100;
Object o = new Object(); @Override
public void run() {
while (true) {
func();
}
}
// 同步方法的锁对象是调用者对象(Runnable对象)
public synchronized void func(){
if (ticket > 0) {
System.out.println(Thread.currentThread().getName() + "-->正在售第" + ticket + "张票!");
ticket--;
}
}
}
实现原理:和同步代码块实现原理基本一致,同步方法中的锁对象是线程实现类的对象。

三、静态方法

package com.staticSyn;

// 买票示例
// 使用同步方法解决线程安全问题
public class TicketRunnableImp implements Runnable {
private static int ticket = 100;
Object o = new Object(); @Override
public void run() {
while (true) {
func();
}
}
// 静态方法的锁对象是本类的class属性
public synchronized static void func(){
if (ticket > 0) {
System.out.println(Thread.currentThread().getName() + "-->正在售第" + ticket + "张票!");
ticket--;
}
}
}

四、Lock锁

方式一

package com.lock1;

import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock; // 买票示例
// 使用同步代码块解决线程安全问题
public class TicketRunnableImp implements Runnable {
private int ticket = 100;
Object o = new Object();
Lock lock=new ReentrantLock();
@Override
public void run() {
while (true) {
lock.lock();
if (ticket > 0) {
System.out.println(Thread.currentThread().getName() + "-->正在售第" + ticket + "张票!");
ticket--;
}
lock.unlock();
}
}
}

方式二

package com.lock2;

import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock; // 买票示例
// 使用同步代码块解决线程安全问题
public class TicketRunnableImp implements Runnable {
private int ticket = 100;
Object o = new Object();
Lock lock = new ReentrantLock(); @Override
public void run() {
while (true) {
lock.lock();
try {
if (ticket > 0) {
System.out.println(Thread.currentThread().getName() + "-->正在售第" + ticket + "张票!");
ticket--;
}
} catch (Exception e) {
System.out.println(e);
} finally {
lock.unlock();
}
}
}
}

五、上述几种方式的测试类

package com.lock2;

public class DemoTicket {
public static void main(String[] args) {
TicketRunnableImp t=new TicketRunnableImp();
Thread t1=new Thread(t);
Thread t2=new Thread(t);
Thread t3=new Thread(t);
t1.start();
t2.start();
t3.start();
}
}

解决线程不安全的方式(Java)的更多相关文章

  1. java 22 - 13 多线程之解决线程安全问题的实现方式2

    上一章说了,解决线程安全问题的实现方式1是使用同步代码块 同时也知道了,同步代码块的锁对象是任意对象:(Object obj ;  Demo d;)这些都行 那么,现在来说解决线程安全问题的实现方式2 ...

  2. java 22 - 12 多线程之解决线程安全问题的实现方式1

    从上一章知道了多线程存在着线程安全问题,那么,如何解决线程安全问题呢? 导致出现问题的原因: A:是否是多线程环境 B:是否有共享数据 C:是否有多条语句操作共享数据 上一章的程序,上面那3条都具备, ...

  3. Java并发编程:Java创建线程的三种方式

    目录 引言 创建线程的三种方式 一.继承Thread类 二.实现Runnable接口 三.使用Callable和Future创建线程 三种方式的对比 引言 在日常开发工作中,多线程开发可以说是必备技能 ...

  4. Java之解决线程安全问题的方式三:Lock锁

    import java.util.concurrent.locks.ReentrantLock; /** * 解决线程安全问题的方式三:Lock锁 --- JDK5.0新增 * * 1. 面试题:sy ...

  5. java线程安全问题以及使用synchronized解决线程安全问题的几种方式

    一.线程安全问题 1.产生原因 我们使用java多线程的时候,最让我们头疼的莫过于多线程引起的线程安全问题,那么线程安全问题到底是如何产生的呢?究其本质,是因为多条线程操作同一数据的过程中,破坏了数据 ...

  6. java——多线程的实现方式、三种办法解决线程赛跑、多线程数据同步(synchronized)、死锁

    多线程的实现方式:demo1.demo2 demo1:继承Thread类,重写run()方法 package thread_test; public class ThreadDemo1 extends ...

  7. Lock锁方式解决线程安全问题

    在JDK5.0之后新增加了一种更强大的线程同步机制---通过显示定义同步锁来实现线程同步解决线程安全问题.同步锁使用Lock对象充当. java.util.concurrent.locks.lock接 ...

  8. java并发之如何解决线程安全问题

    并发(concurrency)一个并不陌生的词,简单来说,就是cpu在同一时刻执行多个任务. 而Java并发则由多线程实现的. 在jvm的世界里,线程就像不相干的平行空间,串行在虚拟机中.(当然这是比 ...

  9. Java实现线程的三种方式和区别

    Java实现线程的三种方式和区别 Java实现线程的三种方式: 继承Thread 实现Runnable接口 实现Callable接口 区别: 第一种方式继承Thread就不能继承其他类了,后面两种可以 ...

  10. Java基础_通过模拟售票情景解决线程不安全问题

    用代码来模拟铁路售票系统,实现通过四个售票点发售某日某次列车的100张车票,一个售票点用一个线程表示 第一种方法:通过继承Thread类的方法创建线程 package com.Gary1; publi ...

随机推荐

  1. 机器学习 | 剖析感知器算法 & Python实现

    前言:本系列博客参考于 <机器学习算法导论>和<Python机器学习> 如有侵权,敬请谅解.本书尽量用总结性的语言重述本书内容,避免侵权. 上一篇已经初步介绍了机器学习相关知识 ...

  2. 通过部署流行 Web 框架掌握 Serverless 技术

    大家好,我是霍大侠,本篇我们通过学习部署流行 Web 框架,如 Spring Boot,Express,Web IDE,让你掌握 Serverless 函数计算架构和技术,领略弹性并发.高可用的好处. ...

  3. 3 分钟将免费无限制的 Claude 2.0 接入任意 GPT 套壳应用,太香了!

    Claude 是 ChatGPT 的最强竞争对手,由 OpenAI 早期团队成员创建,目标就是打造出能 赶超 ChatGPT 的 AI.最新版的 Claude 2.0,能力已经开始领先 ChatGPT ...

  4. socket TCP DPT 网络编程

    复习: ARP协议: 广播和单播 通过ip地址获得mac地址 机器A发起一个arp请求(只包含A的ip地址) 交换机接收到请求,广播这条消息 所有的机器都会接受到这条请求,只有需要寻找的机器B的ip地 ...

  5. Vue之将前端的筛选结果导出为csv文件

    有导入就有导出哈!这里继导入之后记录一下导出的实现过程. 1.按钮部分: <el-button class="filter-item" style="margin- ...

  6. bootstrap : 响应式导航

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8&quo ...

  7. 配置Chrome支持网页内的frame跨域

    前言 跨域限制可以保证安全,但是调试的时候关掉会更方便,然而现在网络上能找到的关闭跨域限制方法,在新版的Chrome浏览器上根本没用-- 经过一番摸索,发现用旧版的Chrome就可以绕过跨域限制,刚好 ...

  8. [转帖]dd - Linux世界中的搬运工

    <存储工具系列文章>主要介绍存储相关的测试和调试工具,包括不限于dd.fio.vdbench.iozone.iometer.cosbench等性能负载工具,及strace等调试工具. dd ...

  9. Oracle AWR学习之二-利用ChatGPT编写一键获取AWR报告的脚本

    Oracle AWR学习之二-ChatGPT提升效率之n 背景 之前生成awr报告比较麻烦, 想着能够一键生成. 再辅以部分shell或者是python处理就可以进行细致的分析. 这一块其实还是比较简 ...

  10. [转帖]PyCharm无法安装第三方模块,一直提示 updating list:time out 解决办法

    Pycharm无法安装第三方模块解决办法: 1.打开pycharm的项目的venv文件夹 2.打开文件夹目录中的pyvenv文件 3.将文件中的include-system-site-packages ...