1,为什么有线程安全问题?

当多个线程同时共享同一个全局变量或静态变量,做写的操作时,可能会发生数据冲突问题,也就是线程安全问题。但是做读操作是不会发生数据冲突问题。

public class TrainThread implements Runnable {

    // 定义初始化票100张
private int ticketCount = 100; public void run() {
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
while (ticketCount > 0) {
System.out.println(Thread.currentThread().getName() + "卖出了第" + (100 - ticketCount + 1 + "张票"));
ticketCount--;
}
} }
public class App {
public static void main(String[] args) throws InterruptedException {
TrainThread trainThread = new TrainThread(); //模拟了两个线程,必须都用同一个Runnable 的子类对象,才能叫 实现资源的共享
Thread thread1 = new Thread(trainThread);
Thread thread2 = new Thread(trainThread);
thread1.start();
thread2.start();
} }

可能出现的情况:同时卖了某一张票

Thread-1卖出了第1张票
Thread-1卖出了第2张票
Thread-0卖出了第1张票
Thread-0卖出了第4张票
Thread-1卖出了第3张票
Thread-1卖出了第6张票

问:为什么使用线程同步或使用锁能解决线程安全问题呢?

答:将可能会发生数据冲突问题(线程不安全问题),只能让当前一个线程进行执行。代码执行完成后释放锁,让后才能让其他线程进行执行。这样的话就可以解决线程不安全问题。

问:什么是多线程之间同步?

答:当多个线程共享同一个资源,不会受到其他线程的干扰

2, 实现线程同步,syncronized 的用法

解决一:

锁对象

syncronized 同步代码块:就是将可能会发生线程安全问题的代码,给包括起来。

synchronized(同一个数据){

 可能会发生线程冲突问题

}

public class TrainThread implements Runnable {

    // 定义初始化票100张
private int ticketCount = 100;
//定义了一个共享的对象
private Object obj = new Object(); public void run() {
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
synchronized (obj) {
while (ticketCount > 0) {
System.out.println(Thread.currentThread().getName() + "卖出了第" + (100 - ticketCount + 1 + "张票"));
ticketCount--;
}
} } }

解决二:

同步函数,

在方法上修饰synchronized 称为同步函数

锁方法

public class TrainThread implements Runnable {

    // 定义初始化票100张
private int ticketCount = 100; public void run() {
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
} sale();
} private synchronized void sale() {
while (ticketCount > 0) {
System.out.println(Thread.currentThread().getName() + "卖出了第" + (100 - ticketCount + 1 + "张票"));
ticketCount--;
}
}
}

3,同步函数,所方法,其实是this 锁

证明,两个线程,一个线程走同步代码块,(锁住了自定义object对象)的代码,

另一个走同步函数,锁方法的的代码,结果数据有冲突,证明了syncronized 没有效,并没有锁住同一资源

将锁对象的object 换成this,则没有数据冲突

4,是静态同步函数?

方法上加上static关键字,使用synchronized 关键字修饰 或者使用类.class文件。

静态的同步函数使用的锁是  该函数所属字节码文件对象

还是加syncronized,和之前没有区别,锁方法

public class TrainThread implements Runnable {

    // 定义初始化票100张
private static int ticketCount = 100; public void run() {
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
sale();
} private synchronized static void sale() {
while (ticketCount > 0) {
System.out.println(Thread.currentThread().getName() + "卖出了第" + (100 - ticketCount + 1 + "张票"));
ticketCount--;
}
}
}

锁当前类的的字节码文件的对象,不是this,或者自定义的对象

public class TrainThread implements Runnable {

    // 定义初始化票100张
private static int ticketCount = 100; public void run() {
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
synchronized (TrainThread.class) {
while (ticketCount > 0) {
System.out.println(Thread.currentThread().getName() + "卖出了第" + (100 - ticketCount + 1 + "张票"));
ticketCount--;
}
}
} }

线程安全,syncronized 用法的更多相关文章

  1. 李洪强iOS开发之FMDB线程安全的用法

    // //  ViewController.m //  04 - FMDB线程安全的用法 // //  Created by 李洪强 on 2017/6/6. //  Copyright © 2017 ...

  2. 一个线程中lock用法的经典实例

    /* 该实例是一个线程中lock用法的经典实例,使得到的balance不会为负数 同时初始化十个线程,启动十个,但由于加锁,能够启动调用WithDraw方法的可能只能是其中几个 作者:http://h ...

  3. AtomicInteger类保证线程安全的用法

    J2SE 5.0提供了一组atomic class来帮助我们简化同步处理.基本工作原理是使用了同步synchronized的方法实现了对一个long, integer, 对象的增.减.赋值(更新)操作 ...

  4. java 线程池的用法

    1.java自带的类ExecutorService用于提供线程池服务,可以一下方法初始化线程池: ExecutorService pool = Executors.newFixedThreadPool ...

  5. Java 四种线程池的用法分析

    1.new Thread的弊端 执行一个异步任务你还只是如下new Thread吗? new Thread(new Runnable() { @Override public void run() { ...

  6. c#基础: 线程的初级用法总结

    启动一个线程的两种方法:     a.使用无参的方法       Thread thread1 = new Thread(new ThreadStart("调用的方法名")):   ...

  7. java--ThreadPool线程池简单用法

    package com.threadPool; import java.util.concurrent.ArrayBlockingQueue; import java.util.concurrent. ...

  8. Android线程之基本用法

    一: 在android中有两种实现线程thread的方法: 一种是,扩展java.lang.Thread类 另一种是,实现Runnable接口 二: Thread类代表线程类,它的两个最主要的方法是: ...

  9. 线程8--GCD常见用法

    1.延迟执行 /***********************延迟第一种方法**************************/ /* 第一种方法, 调用NSObject的方法 [self perf ...

随机推荐

  1. 没有图片的freemarker下载,备份

    没有图片的freemarker下载,备份 //以下代码也可以使用/* public String exportApproveCase(@PathVariable("proId") ...

  2. windows 10 右键菜单注册表位置

    1. 查找 1.1. 打开注册表 # 1. 使用快捷键打开 “运行” win + r # 2. 在 “运行” 中输入 regedit # 3. 回车 1.2. 点击 查找 # 1. 方法 1 : 点击 ...

  3. python随用随学-元类

    python中的一切都是对象 按着我的逻辑走: 首先接受一个公理,「python中的一切都是对象」.不要问为什么,吉大爷(Guido van Rossum,python之父)人当初就是这么设计的,不服 ...

  4. CSS+DIV自适应布局

    CSS+DIV自适应布局 1.两列布局(左右两侧,左侧固定宽度200px;右侧自适应占满) 代码如下: <!doctype html> <html> <head> ...

  5. 基于 Redis 实现 CAS 操作

    基于 Redis 实现 CAS 操作 Intro 在 .NET 里并发情况下我们可以使用 Interlocked.CompareExchange 来实现 CAS (Compare And Swap) ...

  6. JAVA生成EXCEL模板

    JAVA生成excel模板,支持1.必填字段前加 红色 * 2.定义可选值下拉列表 valList3.定义名称并通过名称设置可选值 refName(名称在sheet2,sheet2自动隐藏)4.支持设 ...

  7. Python数据科学手册(1) IPython:超越Python

    1.1 shell还是Notebook Jupyter Notebook 是 IPython shell 基于浏览器的图形界面,提供了一系列丰富的动态展示功能.Jupyter Notebook 不仅可 ...

  8. CrawlSpiders简介

    转:https://www.cnblogs.com/ellisonzhang/p/11124516.html#4295547 一.CrawlSpiders类简介 通过下面的命令可以快速创建 Crawl ...

  9. (转)协议森林12 天下为公 (TCP堵塞控制)

    协议森林12 天下为公 (TCP堵塞控制) 作者:Vamei 出处:http://www.cnblogs.com/vamei 欢迎转载,也请保留这段声明.谢谢! 在TCP协议中,我们使用连接记录TCP ...

  10. go源码分析(二) 使用go http包开发web时遇到的坑之重复注册Handle路由

    我们使用Handle注册http时 如果添加两行,即重复注册函数. http.HandleFunc("/",index) http.HandleFunc("/" ...