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()

具体代码:

 /**
* 继承Thread类
* @date 2019/3/29 11:19
*/
public class SimpleThread extends Thread{ @Override
public void run() {
super.run();
Thread thread = Thread.currentThread();
System.out.println("Thread =>当前执行的线程为:"+thread.getName());
}
} /**
* 实现Runnable接口
* @date 2019/3/29 11:28
*/
public class SimpleRunnable implements Runnable { @Override
public void run() {
Thread thread = Thread.currentThread();
System.out.println("Runnable =>当前执行的线程为:"+thread.getName());
}
} public class TestMain { /**执行线程示例1*/
private static void callSimpleThread(){
int index=10;
for (int i = 0; i < index; i++) {
Thread thread=new SimpleThread();
thread.start();
}
} /**执行线程示例1*/
private static void callSimpleRunnable(){
int index=10;
for (int i = 0; i < index; i++) {
SimpleRunnable simpleRunnable=new SimpleRunnable();
new Thread(simpleRunnable,"Runnable-"+i).start();
}
} public static void main(String[] args) { callSimpleThread(); callSimpleRunnable();
} }

2.多线程安全问题

2.1线程不安全示例

多线程最容易产生的一个问题就是线程安全问题,下面使用一个卖票的例子来体现。
场景描述:现在有两个售票员,一共卖10张车票
 public class SellTicket extends Thread {

     private static int NUMBER = 10;
public SellTicket(String name) {
super(name);
} @Override
public void run() {
String s = "线程:" + Thread.currentThread().getName(); while (NUMBER > 0) {
int i = NUMBER--;
System.out.println(s + " => 卖了第" + i + "号票");
} System.out.println(s + ",票已经卖完");
super.run();
} public static void main(String[] args) { SellTicket thread1 = new SellTicket("售票员A");
thread1.start(); SellTicket thread2 = new SellTicket("售票员B");
thread2.start(); } }

执行结果如下:

我们发现售票员A 和售票员B都卖了10号票,这就是线程不安全导致的结果

2.2线程不安全解决方法

方案一:使用同步代码解决
格式:synchronized(锁对象){需要被同步的代码}
锁对象可以为this锁,也可以自定义对象锁 方案二:使用同步函数解决
同步函数就是使用synchronized修饰一个函数

下面采用同步代码块解决

 public class SafetySellTicket extends Thread {

     private static int NUMBER = 10;

     @Override
public void run() {
String s = "线程:" + Thread.currentThread().getName(); while (NUMBER > 0) {
synchronized (this) {
if (NUMBER > 0) {
int i = NUMBER--;
System.out.println(s + " => 卖了第" + i + "号票");
} else {
System.out.println(s + ",票已经卖完");
break;
} }
}
super.run();
} public static void main(String[] args) { SafetySellTicket thread1 = new SafetySellTicket();
thread1.start(); SafetySellTicket thread2 = new SafetySellTicket();
thread2.start(); } }

【Java并发编程一】线程安全问题的更多相关文章

  1. Java并发编程基础-线程安全问题及JMM(volatile)

    什么情况下应该使用多线程 : 线程出现的目的是什么?解决进程中多任务的实时性问题?其实简单来说,也就是解决“阻塞”的问题,阻塞的意思就是程序运行到某个函数或过程后等待某些事件发生而暂时停止 CPU 占 ...

  2. Java并发编程:线程池的使用

    Java并发编程:线程池的使用 在前面的文章中,我们使用线程的时候就去创建一个线程,这样实现起来非常简便,但是就会有一个问题: 如果并发的线程数量很多,并且每个线程都是执行一个时间很短的任务就结束了, ...

  3. Java并发编程:线程间协作的两种方式:wait、notify、notifyAll和Condition

    Java并发编程:线程间协作的两种方式:wait.notify.notifyAll和Condition 在前面我们将了很多关于同步的问题,然而在现实中,需要线程之间的协作.比如说最经典的生产者-消费者 ...

  4. Java并发编程:线程池的使用(转)

    Java并发编程:线程池的使用 在前面的文章中,我们使用线程的时候就去创建一个线程,这样实现起来非常简便,但是就会有一个问题: 如果并发的线程数量很多,并且每个线程都是执行一个时间很短的任务就结束了, ...

  5. Java并发编程:线程控制

    在上一篇文章中(Java并发编程:线程的基本状态)我们介绍了线程状态的 5 种基本状态以及线程的声明周期.这篇文章将深入讲解Java如何对线程进行状态控制,比如:如何将一个线程从一个状态转到另一个状态 ...

  6. Java 并发编程:线程间的协作(wait/notify/sleep/yield/join)

    Java并发编程系列: Java 并发编程:核心理论 Java并发编程:Synchronized及其实现原理 Java并发编程:Synchronized底层优化(轻量级锁.偏向锁) Java 并发编程 ...

  7. (转)Java并发编程:线程池的使用

    背景:线程池在面试时候经常遇到,反复出现的问题就是理解不深入,不能做到游刃有余.所以这篇博客是要深入总结线程池的使用. ThreadPoolExecutor的继承关系 线程池的原理 1.线程池状态(4 ...

  8. Java并发编程:线程池的使用(转载)

    转载自:https://www.cnblogs.com/dolphin0520/p/3932921.html Java并发编程:线程池的使用 在前面的文章中,我们使用线程的时候就去创建一个线程,这样实 ...

  9. Java并发编程:线程池的使用(转载)

    文章出处:http://www.cnblogs.com/dolphin0520/p/3932921.html Java并发编程:线程池的使用 在前面的文章中,我们使用线程的时候就去创建一个线程,这样实 ...

  10. [转]Java并发编程:线程池的使用

    Java并发编程:线程池的使用 在前面的文章中,我们使用线程的时候就去创建一个线程,这样实现起来非常简便,但是就会有一个问题: 如果并发的线程数量很多,并且每个线程都是执行一个时间很短的任务就结束了, ...

随机推荐

  1. Angular记录(3)

    文档资料 箭头函数--MDN:https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Functions/Arrow_fun ...

  2. 【转】Redis学习笔记(五)如何用Redis实现分布式锁(2)—— 集群版

    原文地址:http://bridgeforyou.cn/2018/09/02/Redis-Dsitributed-Lock-2/ 单机版实现的局限性 在上一篇文章中,我们讨论了Redis分布式锁的实现 ...

  3. ArcGis——好好的属性表,咋就乱码了呢?

    我就瞎说一下,反正你也不懂. ——见到许多ArcGis属性表乱码的问题,也见过各种哭笑不得的解说 目录 第一节 字符编码那些事儿→字符编码简述 第二节 都是编码惹的祸→ArcGis属性表出错原因 第三 ...

  4. XGBoost参数调优完全指南

    简介 如果你的预测模型表现得有些不尽如人意,那就用XGBoost吧.XGBoost算法现在已经成为很多数据工程师的重要武器.它是一种十分精致的算法,可以处理各种不规则的数据.构造一个使用XGBoost ...

  5. sql server 查询log日志 sql语句

    xp_readerrorlog 一共有7个参数: 1. 存档编号 2. 日志类型(1为SQL Server日志,2为SQL Agent日志) 3. 查询包含的字符串 4. 查询包含的字符串 5. Lo ...

  6. django在windows下的经历

    django-admin.py startproject project_name 去掉.py 常见命令:https://blog.csdn.net/weixin_42134789/article/d ...

  7. win10只有edge浏览器能上网的解决方法

    问题描述:电脑就只有edge浏览器和自带的邮件可以上网,但是QQ Chrome,360浏览器都无法上网: 解决方法:打开命令提示符(管理员),执行netsh winsock reset,重启系统就好了 ...

  8. SQL优化传送门

    转载:pursuer.chen的SQL Server 容易忽略的错误 链接:https://www.cnblogs.com/chenmh/p/3999475.html

  9. ASP.NET Core 项目配置 ( Startup )(转载)

    原文:https://www.twle.cn/l/yufei/aspnetcore/dotnet-aspnet-startup.html 由于是个人网站,怕没了,特意复制保存,个人觉得讲的非常透彻 前 ...

  10. 统计信息不准导致sql性能下降

    某局的预生产系统一条sql语句20分钟执行完,上线以后2个小时没执行出来,在预生产执行计划是hash join在生产是nested loop,通过awr基表wri$_optstat_tab_histo ...