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. python 学习 leetcode ---number of island

    Given a 2d grid map of '1's (land) and '0's (water), count the number of islands. An island is surro ...

  2. PHP数组函数详解大全

    一.数组操作的基本函数 数组的键名和值 array_values($arr);获得数组的值 array_keys($arr);获得数组的键名 array_flip($arr);数组中的值与键名互换(如 ...

  3. 第十七节,OpenCV(学习六)图像轮廓检测

    1.检测轮廓 轮廓检测是图像处理中经常用到的,OpenCV-Python接口中使用cv2.findContours()函数查找检测物体的轮廓. cv2.findContours(image, mode ...

  4. RNN,写起来真的烦

    曾经,为了处理一些序列相关的数据,我稍微了解了一点递归网络 (RNN) 的东西.由于当时只会 tensorflow,就从官网上找了一些 tensorflow 相关的 demo,中间陆陆续续折腾了两个多 ...

  5. 添加一个非模态对话框在revit中

    RequestHandler handler = new RequestHandler(); ExternalEvent exEvent = ExternalEvent.Create(handler) ...

  6. shell编程练习-打印九九乘法表(附:awk编程)

    小练习,仅供参考 shell编写 #!/bin/bash for i in {1..9}do for j in {1..9} do if [ $j -le $i ] ;then echo -ne &q ...

  7. 【medium】990. Satisfiability of Equality Equations 并查集

    Given an array equations of strings that represent relationships between variables, each string equa ...

  8. Python logging日志系统

    写我小小的日志系统 配置logging有以下几种方式: 1)使用Python代码显式的创建loggers, handlers和formatters并分别调用它们的配置函数: 2)创建一个日志配置文件, ...

  9. 试题 E: 迷宫

    [问题描述]下图给出了一个迷宫的平面图,其中标记为 1 的为障碍,标记为 0 的为可以通行的地方.010000000100001001110000迷宫的入口为左上角,出口为右下角,在迷宫中,只能从一个 ...

  10. GitLab实战操作指南

    一.Git原理 1.Git是什么? Git是目前世界上最先进的分布式版本控制系统(没有之一). 2.Git有什么特点? 简单来说就是:高端大气上档次! 3.GIt与SVN区别 SVN管理: 属于集中式 ...