【Java并发编程一】线程安全问题
1.多线程的实现
多线程有两种实现方式:
1.1.继承Thread类 =>示例:A a=new A(); a.start();
1.2.实现Runnable接口 =>示例:A a=new A(); new Thread(A,自定义线程名称).start();
其实Thread和Runnable都实现了run方法,这种操作模式其实就是代理模式
获取当前线程名称:Thread.currentThread().getName()
调用线程是thread.start(),真正执行线程是 thread.run()
具体代码:
1 /** 2 * 继承Thread类 3 * @date 2019/3/29 11:19 4 */ 5 public class SimpleThread extends Thread{ 6 7 @Override 8 public void run() { 9 super.run(); 10 Thread thread = Thread.currentThread(); 11 System.out.println("Thread =>当前执行的线程为:"+thread.getName()); 12 } 13 } 14 15 /** 16 * 实现Runnable接口 17 * @date 2019/3/29 11:28 18 */ 19 public class SimpleRunnable implements Runnable { 20 21 @Override 22 public void run() { 23 Thread thread = Thread.currentThread(); 24 System.out.println("Runnable =>当前执行的线程为:"+thread.getName()); 25 } 26 } 27 28 public class TestMain { 29 30 31 /**执行线程示例1*/ 32 private static void callSimpleThread(){ 33 int index=10; 34 for (int i = 0; i < index; i++) { 35 Thread thread=new SimpleThread(); 36 thread.start(); 37 } 38 } 39 40 /**执行线程示例1*/ 41 private static void callSimpleRunnable(){ 42 int index=10; 43 for (int i = 0; i < index; i++) { 44 SimpleRunnable simpleRunnable=new SimpleRunnable(); 45 new Thread(simpleRunnable,"Runnable-"+i).start(); 46 } 47 } 48 49 public static void main(String[] args) { 50 51 callSimpleThread(); 52 53 callSimpleRunnable(); 54 } 55 56 }
2.多线程安全问题
2.1线程不安全示例
多线程最容易产生的一个问题就是线程安全问题,下面使用一个卖票的例子来体现。
场景描述:现在有两个售票员,一共卖10张车票
1 public class SellTicket extends Thread { 2 3 private static int NUMBER = 10; 4 public SellTicket(String name) { 5 super(name); 6 } 7 8 @Override 9 public void run() { 10 String s = "线程:" + Thread.currentThread().getName(); 11 12 while (NUMBER > 0) { 13 int i = NUMBER--; 14 System.out.println(s + " => 卖了第" + i + "号票"); 15 } 16 17 System.out.println(s + ",票已经卖完"); 18 super.run(); 19 } 20 21 22 public static void main(String[] args) { 23 24 SellTicket thread1 = new SellTicket("售票员A"); 25 thread1.start(); 26 27 SellTicket thread2 = new SellTicket("售票员B"); 28 thread2.start(); 29 30 } 31 32 }
执行结果如下:
我们发现售票员A 和售票员B都卖了10号票,这就是线程不安全导致的结果
2.2线程不安全解决方法
方案一:使用同步代码解决格式:synchronized(锁对象){需要被同步的代码}锁对象可以为this锁,也可以自定义对象锁 方案二:使用同步函数解决同步函数就是使用synchronized修饰一个函数
下面采用同步代码块解决
1 public class SafetySellTicket extends Thread { 2 3 private static int NUMBER = 10; 4 5 @Override 6 public void run() { 7 String s = "线程:" + Thread.currentThread().getName(); 8 9 while (NUMBER > 0) { 10 synchronized (this) { 11 if (NUMBER > 0) { 12 int i = NUMBER--; 13 System.out.println(s + " => 卖了第" + i + "号票"); 14 } else { 15 System.out.println(s + ",票已经卖完"); 16 break; 17 } 18 19 } 20 } 21 super.run(); 22 } 23 24 25 public static void main(String[] args) { 26 27 SafetySellTicket thread1 = new SafetySellTicket(); 28 thread1.start(); 29 30 SafetySellTicket thread2 = new SafetySellTicket(); 31 thread2.start(); 32 33 } 34 35 }
转载于:https://www.cnblogs.com/IT-study/p/10690605.html
【Java并发编程一】线程安全问题相关推荐
- java并发编程与线程安全
2019独角兽企业重金招聘Python工程师标准>>> 什么是线程安全 如果对象的状态变量(对象的实例域.静态域)具有可变性,那么当该对象被多个线程共享时就的考虑线程安全性的问题,否 ...
- JAVA并发编程3_线程同步之synchronized关键字
在上一篇博客里讲解了JAVA的线程的内存模型,见:JAVA并发编程2_线程安全&内存模型,接着上一篇提到的问题解决多线程共享资源的情况下的线程安全问题. 不安全线程分析 public clas ...
- 【Java 并发编程】线程池机制 ( ThreadPoolExecutor 线程池构造参数分析 | 核心线程数 | 最大线程数 | 非核心线程存活时间 | 任务阻塞队列 )
文章目录 前言 一.ThreadPoolExecutor 构造参数 二.newCachedThreadPool 参数分析 三.newFixedThreadPool 参数分析 四.newSingleTh ...
- 【Java 并发编程】线程池机制 ( 线程池示例 | newCachedThreadPool | newFixedThreadPool | newSingleThreadExecutor )
文章目录 前言 一.线程池示例 二.newCachedThreadPool 线程池示例 三.newFixedThreadPool 线程池示例 三.newSingleThreadExecutor 线程池 ...
- (转)Java并发编程:线程池的使用
背景:线程池在面试时候经常遇到,反复出现的问题就是理解不深入,不能做到游刃有余.所以这篇博客是要深入总结线程池的使用. ThreadPoolExecutor的继承关系 线程池的原理 1.线程池状态(4 ...
- 19、Java并发编程:线程间协作的两种方式:wait、notify、notifyAll和Condition
Java并发编程:线程间协作的两种方式:wait.notify.notifyAll和Condition 在前面我们将了很多关于同步的问题,然而在现实中,需要线程之间的协作.比如说最经典的生产者-消费者 ...
- [转]Java并发编程:线程池的使用
Java并发编程:线程池的使用 在前面的文章中,我们使用线程的时候就去创建一个线程,这样实现起来非常简便,但是就会有一个问题: 如果并发的线程数量很多,并且每个线程都是执行一个时间很短的任务就结束了, ...
- Java并发编程:线程的同步
<?xml version="1.0" encoding="utf-8"?> Java并发编程:线程的同步 Java并发编程:线程的同步 Table ...
- Java并发编程一线程池简介
推荐:Java并发编程汇总 Java并发编程一线程池简介 为什么我们需要使用线程池? 我们知道线程是一种比较昂贵的资源,我们通过程序每创建一个线程去执行,其实操作系统都会对应地创建一个线程去执行我们的 ...
- Java并发编程一线程池的五种状态
推荐:Java并发编程汇总 Java并发编程一线程池的五种状态 原文地址 Java多线程线程池(4)–线程池的五种状态 正文 线程池的5种状态:Running.ShutDown.Stop.Tidyin ...
最新文章
- Uva - 12050 Palindrome Numbers【数论】
- 逃离伪PHP程序员应该做的事
- [转]js escape,encodeURI,encodeURIComponent
- python绘制3d图-Python matplotlib绘图示例 - 绘制三维图形
- scala 操作hdfs
- 随笔(很晚很晚,瞎写一通)
- LiveVideoStackCon深圳-AI无孔不入
- Instagram 在 PyCon 2017 的演讲摘要
- mysql设计一个简单的系统_一个简单数据库设计例子
- RabbitMQ学习系列(一): 介绍
- 嵌入式IAP开发笔记之一:面向STM32的BootLoader程序
- Python+pywin32操作Excel文件常用功能(268行代码+注释)
- IDEA下项目打包成jar,并通过cmd命令调用
- mtk2503 如何支持使用epo?
- python3 类中方法的调用
- 委托学习——4. 委托的高级使用
- java翻译程序_有没有java代码翻译软件?
- 存储运维知识点记录(netapp,华为,HP-3par,emc)
- 单元格颜色公式之明细数据项隔行底纹
- revit建模插件:不规则幕墙如何在Revit中创建呢?
热门文章
- MYSQL 横向展示数据
- info matlab,c – 在OpenCV中是否有类似MATLAB的’impixelinfo()’功能?
- GDAL C# “OSGeo.GDAL.GdalPINVOKE”的类型初始值设定项引发异常 解决方法
- 更改shape文件字段名,提示Failed to alter the name of the field
- FlashDevelop打包IOS应用教程
- 【java学习之路】(java框架)003.Mybatis的介绍和基本使用
- 计算机组成原理中EMAR是什么,计算机组成原理复习资料+试题
- android studio创建项目一直,Android Studio在创建/导入项目的时候,一直处于building “XXX”gradle project info的解决办法...
- mysql yum安装和 rpm安装_yum 和 rpm安装mysql彻底删除
- HUE与YARN的集成