1.使用synchronized关键字修饰类或者代码块;

2.使用Volatile关键字修饰变量;

3.在类中加入重入锁

举例子:多个线程在处理一个共享变量的时候,就会出现线程安全问题。(相当于多个窗口卖票的操作)

非同步状态下:

public static void main(String[] args){
Increase increase = new Increase();
int count = 10;
while (count != 0){
new Thread(() -> {
increase.increasementAndPrint();
}).start();
count --;
}
} static class Increase {
private int i = 0; void increasementAndPrint() {
System.out.print(i++ + "\n");
}
}

这种情况下可能会导致多个线程输出的i相同:

0
0
1
2
3
4
5
6
7
8

使用同步:

1.使用synchronized关键字
//保证原子性和有序性
static class Increase {
private int i = 0; synchronized void increasementAndPrint() {
System.out.println(i++);
}
}
2.使用volatile
//不保证原子性(一个被volatile声明的变量主要有可见性,有序性)
static class Increase {
private volatile int i = 0; void increasementAndPrint() {
System.out.println(i++);
}
}

volatile关键字不一定能够保证线程安全的问题,其实,在大多数情况下volatile还是可以保证变量的线程安全问题的。所以,在满足以下两个条件的情况下,volatile就能保证变量的线程安全问题:

  1. 运算结果并不依赖变量的当前值,或者能够确保只有单一的线程修改变量的值。
3.使用重入锁
//保证原子性和有序性
static class Increase {
private ReentrantLock reentrantLock = new ReentrantLock();
private int i = 0; void increasementAndPrint() {
reentrantLock.lock();
System.out.println(i++);
reentrantLock.unlock();
}
}

Java同步的三种实现方式的更多相关文章

  1. Java多线程的三种实现方式

    java多线程的三种实现方式 一.继承Thread类 二.实现Runnable接口 三.使用ExecutorService, Callable, Future 无论是通过继承Thread类还是实现Ru ...

  2. java的list几种实现方式的效率(ArrayList、LinkedList、Vector、Stack),以及 java时间戳的三种获取方式比较

    一.list简介 List列表类,顺序存储任何对象(顺序不变),可重复. List是继承于Collection的接口,不能实例化.实例化可以用: ArrayList(实现动态数组),查询快(随意访问或 ...

  3. Java定时器的三种实现方式

    一.普通thread /** * 普通thread * 这是最常见的,创建一个thread,然后让它在while循环里一直运行着, * 通过sleep方法来达到定时任务的效果.这样可以快速简单的实现, ...

  4. Java数组的三种打印方式

    1.数组的输出的三种方式 一维数组: 定义一个数组 int[] array = {1,2,3,4,5}; (1)传统的for循环方式 for(int i=0;i<array.length;i++ ...

  5. Java反射的三种实现方式

    Foo foo = new Foo(); 第一种:通过Object类的getClass方法 Class cla = foo.getClass(); 第二种:通过对象实例方法获取对象 Class cla ...

  6. java 代理的三种实现方式

    Java 代理模式有如下几种实现方式: 1.静态代理. 2.JDK动态代理. 3.CGLIB动态代理. 示例,有一个打招呼的接口.分别有两个实现,说hello,和握手.代码如下. 接口: public ...

  7. java 多线程编程三种实现方式

    一种是继承Thread类,一种是实现Runable接口,还有一种是实现callable接口: 有博主说只有前面2种方式,我个人愚见是三种,主要详细介绍下callable的使用: 三种线程的我的个人理解 ...

  8. java集合的三种遍历方式

    import java.util.ArrayList;  import java.util.Collection;import java.util.Iterator;public class Home ...

  9. java线程的三种实现方式

    线程实现的三种种方式: 一个是继承Thread类,实现run()方法: 一个是实现Runnable接口,实现run()方法: 一个是实现Callable接口,实现call()方法:该方式和实现Runn ...

随机推荐

  1. kendo grid结合ajax功能

    我感觉使用ajax结合表格绑定效率更好一些,可以灵活的控制点击前后的事件,现在grid前后的事件我不能控制

  2. Hibernate数据缓存攻略

    目录 第一章 缓存策略概述 第二章 hibernate不使用缓存的问题 第三章 一级缓存介绍 第四章 二级缓存 第五章 一二级缓存对比及总结 源代码: https://github.com/weili ...

  3. thymeleaf模板使用th:onclick进行传参

    错误的写法: th:onclick="'javascript:editUser('+${prod.id}+');'" 正确的写法: th:onclick="'javasc ...

  4. AngularJS:实现页面滚动到底自动加载数据的功能

    要实现这个功能,可以通过https://github.com/sroze/ngInfiniteScroll这个第三方控件来实现.步骤如下: 1. 下载ng-infinite-scroll.js程序ht ...

  5. FineReport实线java报表填报录入的效果图

    Java报表-固定资产(增删改) Java报表-集团財务报表 Java报表-简单自由填报 Java报表-客户跟踪数据回填 Java报表-客户关系复杂填报 Java报表-批量导入 Java报表-批量删除 ...

  6. FZU 1894 志愿者选拔【单调队列】【monotone decreasing queue】

     Problem 1894 志愿者选拔 Accept: 1770    Submit: 5523 Time Limit: 1500 mSec    Memory Limit : 32768 KB  P ...

  7. 在win10 64 bit上安装theano

    在windows10上安装theano,过程例如以下: 1.准备工作.先安装Anaconda 64位.然后执行 conda install mingw libpython 2.先安装pycuda,能够 ...

  8. Android TextView 设置行间距

    Android系统中TextView默认显示中文时会比较紧凑,不是很美观.为了让每行保持一定的行间距,可以设置属性android:lineSpacingExtra或android:lineSpacin ...

  9. Android内存解析(二)— 详解内存,内部存储和外部存储

    总述 觉得十分有必要搞清楚内存,内部存储和外部存储的区别,还有我们在开发中真正将数据存在了手机的哪儿. 先提一个问题:手机设置的应用管理中,每个App下都有清除数据和清除缓存,清除的分别是哪里的数据? ...

  10. Codeforces--630K--Indivisibility(容斥)

     K - Indivisibility Crawling in process... Crawling failed Time Limit:500MS     Memory Limit:65536 ...