Java基础-多线程-②多线程的安全问题

什么是线程的安全问题?

上一篇 Java基础-多线程-①线程的创建和启动 我们说使用实现Runnable接口的方式来创建线程,可以实现多个线程共享资源:

 1 class Dog implements Runnable {
 2     // 定义线程共享数据
 3     private int t = 100;
 4
 5     @Override
 6     public void run() {
 7         // TODO:死循环,暂不处理
 8         while (true) {
 9             if (t > 0) {
10
11                 System.out.println("当前线程:" + Thread.currentThread().getName() + "---" + t--);
12             }
13         }
14     }
15 }
16
17 public class ThreadDemo {
18     public static void main(String[] args) {
19         System.out.println("当前线程:" + Thread.currentThread().getName());
20         Dog dog = new Dog();
21
22         Thread thread = new Thread(dog);
23         Thread thread2 = new Thread(dog);
24         thread.start();
25         thread2.start();
26
27     }
28 }

开启两个线程,共享数据t=100,执行run方法中的代码:当t大于0时,打印t--。分析一下可能会存在的问题:

因为CPU时间片快速切换的不确定性,该问题不一定会发生,为了模拟一下该问题的发生,在打印语句执行前,让线程睡眠0.1秒:

 1 @Override
 2 public void run() {
 3     while (true) {
 4         if (t > 0) {
 5             try {
 6                 Thread.sleep(100);
 7                 System.out.println("当前线程:" + Thread.currentThread().getName() + "---" + t--);
 8             } catch (InterruptedException e) {
 9                 //TODO:暂不处理异常
10             }
11         }
12     }
13 }                                                                                                      

问题产生的原因

首先我们想到是因为两个线程共享了数据t。如果多个线程不涉及数据共享,各自执行自己的代码,就不会出现这个问题。在线程不安全的单例模式中,就涉及到这个问题。

①多个线程共享了数据。

如果我们不判断t>0,直接打印t--,或者只判断t>0,不执行t--,只要循环不结束,程序不终止,从逻辑上来说,程序也没有问题

②在线程任务中设计对共享数据的操作(这里的操作包括①判断t>0;②执行t--),一个线程在操作共享数据的时候,其他的线程也操作了共享数据。

这时候就可能造成数据出错。

总结来说,多个线程在执行同一段代码的时候,每次的执行结果和单线程执行的结果都是一样的,不存在执行结果的二义性,就可以称作是线程安全的。线程安全问题多是由全局变量和静态变量引起的,当多个线程对共享数据只执行读操作,不执行写操作时,一般是线程安全的;当多个线程都执行写操作时,需要考虑线程同步来解决线程安全问题。

Java基础-多线程-②多线程的安全问题,布布扣,bubuko.com

时间: 2024-10-08 10:29:31

Java基础-多线程-②多线程的安全问题的相关文章

3.8 java基础总结①多线程

多线程 多线程这章理论大于实践,因为在实际开发中多线程的都封装到框架里边了的,程序员一般不会写多线程,多线程属于Java里边比较底层的代码了. 线程是处理器调度的最基本单位程序>进程>线程程序是死的,当启动程序得时候会有一个或几个进程,每个进程里边可以有诺干线程.基于线程开销更 创建线程:两种方法1.声明Thread的子类,重写run方法class MyThread extends Thread{ public void run(){ }}Mythread a = new MyThread()

【BigData】Java基础_多线程

所谓的多线程就像小吃街卖铜锅米线的老板,老板就好比一个操作系统,如果5个顾客同时去买米线,那么,此时老板就会同时准备好5个铜锅,然后同时放上水.调料.米线,同时煮5个人的米线,如果逐个煮的话,那么估计煮了2个人的米线,后面3人就来找老板退款了. 官方解释:多线程(英语:multithreading),是指从软件或者硬件上实现多个线程并发执行的技术 在Java中实现多线程四部曲: (1)将需要用多线程方式执行的逻辑,写入一个runnable实现类中(run方法中): (2)创建出这个runnabl

Java基础4——多线程

线程依赖于进程而存在 进程:正在运行的程序 是操作系统进行资源分配和调度的独立单位 每个进程都有自己的内存空间和系统资源 多进程的意义:单进程的计算机只能做一件事情 DOS窗口就是典型的单进程 多进程的计算机可以在一个时间段内执行多个任务 单核CPU在某个时间点只能执行一件事情,事实上CPU一直在高效切换各个进程 线程:一个进程内可以执行多个任务,每个任务可以看成是一个线程,线程是程序(进程)的执行单元或执行路径,是程序使用CPU的最小单位 多线程的意义:提高应用程序的使用率 程序的执行都是在抢

黑马程序员-Java基础之多线程

多线程 进程:正在进行中的程序.其实进程就是一个应用程序运行时的内存分配空间. 线程:其实就是进程中一个程序执行控制单元,一条执行路径.进程负责的是应用程序的空间的标示.线程负责的是应用程序的执行顺序. 一个进程至少有一个线程在运行,当一个进程中出现多个线程时,就称这个应用程序是多线程应用程序,每个线程在栈区中都有自己的执行空间,自己的方法区.自己的变量. jvm在启动的时,首先有一个主线程,负责程序的执行,调用的是main函数.主线程执行的代码都在main方法中. 当产生垃圾时,收垃圾的动作,

java基础之 多线程

总结学习,我认为是一个非常好的学习方法. 写在前面[摘]: 作为一名Java开发人员,不管作为面试官,还是被面试的对象,甚至是两者兼有.Java线程技术的考察,势必成为整个面试过程的重点之一.分析一下原因,不难发现,实际工作当中,涉及到的Java应用几乎全是多线程,单线程Java应用微乎其微.如何管理好多线程的调度,比如线程的安全问题,是Java应用实现高效并行运行的关键点之一,也是摆在大多数Java初学者的难题. 多线程 我从以下几个方面进行知识总结: 一.概述 操作系统可以同时执行多个任务,

JAVA基础9(多线程)

1:多线程 (1)线程是依赖于进程而存在的. A.进程正在运行的应用程序 B.线程进程的执行路径,执行单元 (2)多线程的两种方案: 继承Thread类: 实现Runable接口: public class MyThread implements Runnable{ //实现runnable接口 public void run() { //启动该线程对象之后,需要执行的代码 for (int i = 0; i < 10; i++) { System.out.println(i); } } } p

Java基础知识—多线程编程(五)

概述 Java 给多线程编程提供了内置的支持.一个多线程程序包含两个或多个能并发运行的部分.程序的每一部分都称作一个线程,并且每个线程定义了一个独立的执行路径.使用多线程也是为了充分的利用服务器资源,提高工作效率. 线程生命周期 线程是一个动态执行的过程,它也有一个从产生到死亡的过程. 新建状态: 使用 new 关键字和 Thread 类或其子类建立一个线程对象后,该线程对象就处于新建状态.它保持这个状态直到程序 start() 这个线程. 就绪状态: 当线程对象调用了start()方法之后,该

Java基础笔记-多线程

线程: 方式一:继承Thread类并且复写run方法. 格式: class MyThread extends Thread { public void run() { 线程中要运行的代码. } } 其步骤为: 1.定义类继承Thread类. 2.复习run方法.---->目的是:用于存储线程中要运行的代码,将自定义的代码存储在run方法中,让线程运行. 3.调用线程的start方法 注意:不是调用run方法. 线程的名字:一般线程有默认的名字,形式为:Thread-编号,编号是从0开始标记的.

java基础之多线程

参考博客 http://www.mamicode.com/info-detail-517008.html 1.进程和线程的区别 进程:每个进程都有独立的代码和数据空间(进程上下文),进程间的切换会有较大的开销,一个进程包含1--n个线程. 线程:同一类线程共享代码和数据空间,每个线程有独立的运行栈和程序计数器(PC),线程切换开销小. 线程和进程一样分为五个阶段:创建.就绪.运行.阻塞.终止. 多进程是指操作系统能同时运行多个任务(程序). 多线程是指在同一程序中有多个顺序流在执行. 2.实现R

java基础及多线程

1.多线程 1.1.进程与线程 ? 进程就是一个运行中的程序. ? 一个进程中可以有多个线程,线程是CPU调度和分派的基本单位.我们可以理解为线程就是程序运行中的一条路径. 1.2.多线程的创建及使用 1.2.1.创建 自定义一个类继承Thread类或实现Runnable接口 1.2.2:两种创建多线程的区别 继承Thread类:Thread()或Thread(String name) 多个线程分别完成自己的任务 实现Runnable接口:Thread(Runnable target) 或Thr