一、原子性操作

1、ThreadLocal

不同线程操作同一个 ThreadLocal 对象执行各种操作而不会影响其他线程里的值

注意:虽然ThreadLocal很有用,但是它作为一种线程级别的全局变量,如果某些代码依赖它的话,会造成耦合,从而影响了代码的可重用性

2、变量声明为 final

public class FinalDemo {
private final int finalField; public FinalDemo(int finalField) {
this.finalField = finalField;
}
}

3、加锁

在同步代码块中的代码要尽量的短,不要把不需要同步的代码也加入到同步代码块,在同步代码块中千万不要执行特别耗时或者可能发生阻塞的一些操作,比如I/O操作啥的。

某个线程在进入某个同步代码块的时候去获取一个锁,在退出该代码块的时候把锁给释放掉

public class Increment {
private int i; private Object lock = new Object(); public void increase(){
synchronized (lock){
i++;
}
} public int getI(){
synchronized (lock){
return i;
}
} public static void test(int threadNum,int loopTimes){
Increment increment = new Increment(); Thread[] threads = new Thread[threadNum];
for(int i = 0; i<threads.length;i++){
Thread t = new Thread(new Runnable() {
@Override
public void run() {
for(int i = 0; i < loopTimes;i++){
increment.increase();
}
}
});
threads[i] = t;
t.start();
} for (Thread t : threads) { //main线程等待其他线程都执行完成
try {
t.join();
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
} System.out.println(threadNum + "个线程,循环" + loopTimes + "次结果:" + increment.getI());
} public static void main(String[] args) {
test(20, 1);
test(20, 10);
test(20, 100);
test(20, 1000);
test(20, 10000);
test(20, 100000);
}
}

二 锁的重入

只要一个线程持有了某个锁,那么它就可以进入任何被这个锁保护的代码块。

ublic class SynchronizedDemo {

    private Object lock = new Object();

    public void m1() {
synchronized (lock) {
System.out.println("这是第一个方法");
m2();
}
} public void m2() {
synchronized (lock) {
System.out.println("这是第二个方法");
}
} public static void main(String[] args) {
SynchronizedDemo synchronizedDemo = new SynchronizedDemo();
synchronizedDemo.m1();
}
}

三、同步方法

public class Increment {

    private int i;

    public void increase() {
synchronized (this) { //使用this作为锁
i++;
}
} public static void anotherStaticMethod() {
synchronized (Increment.class) { //使用Class对象作为锁
// 此处填写需要同步的代码块
}
}
}

可以简写成:

public class Increment {

    private int i;

    public synchronized increase() {   //使用this作为锁
i++;
} public synchronized static void anotherStaticMethod() { //使用Class对象作为锁
// 此处填写需要同步的代码块
}
}

02.java并发编程之原子性操作的更多相关文章

  1. Java并发编程实战 03互斥锁 解决原子性问题

    文章系列 Java并发编程实战 01并发编程的Bug源头 Java并发编程实战 02Java如何解决可见性和有序性问题 摘要 在上一篇文章02Java如何解决可见性和有序性问题当中,我们解决了可见性和 ...

  2. Java 并发编程(二):如何保证共享变量的原子性?

    线程安全性是我们在进行 Java 并发编程的时候必须要先考虑清楚的一个问题.这个类在单线程环境下是没有问题的,那么我们就能确保它在多线程并发的情况下表现出正确的行为吗? 我这个人,在没有副业之前,一心 ...

  3. Java并发编程(您不知道的线程池操作), 最受欢迎的 8 位 Java 大师,Java并发包中的同步队列SynchronousQueue实现原理

    Java_并发编程培训 java并发程序设计教程 JUC Exchanger 一.概述 Exchanger 可以在对中对元素进行配对和交换的线程的同步点.每个线程将条目上的某个方法呈现给 exchan ...

  4. Java并发编程入门与高并发面试(三):线程安全性-原子性-CAS(CAS的ABA问题)

    摘要:本文介绍线程的安全性,原子性,java.lang.Number包下的类与CAS操作,synchronized锁,和原子性操作各方法间的对比. 线程安全性 线程安全? 线程安全性? 原子性 Ato ...

  5. Java并发编程之验证volatile不能保证原子性

    Java并发编程之验证volatile不能保证原子性 通过系列文章的学习,凯哥已经介绍了volatile的三大特性.1:保证可见性 2:不保证原子性 3:保证顺序.那么怎么来验证可见性呢?本文凯哥(凯 ...

  6. Java并发编程(您不知道的线程池操作)

    Java并发编程(您不知道的线程池操作) 这几篇博客,一直在谈线程,设想一下这个场景,如果并发的线程很多,然而每个线程如果执行的时间很多的话,这样的话,就会大量的降低系统的效率.这时候就可以采用线程池 ...

  7. 原创】Java并发编程系列2:线程概念与基础操作

    [原创]Java并发编程系列2:线程概念与基础操作 伟大的理想只有经过忘我的斗争和牺牲才能胜利实现. 本篇为[Dali王的技术博客]Java并发编程系列第二篇,讲讲有关线程的那些事儿.主要内容是如下这 ...

  8. Java并发编程:volatile关键字解析

    Java并发编程:volatile关键字解析 volatile这个关键字可能很多朋友都听说过,或许也都用过.在Java 5之前,它是一个备受争议的关键字,因为在程序中使用它往往会导致出人意料的结果.在 ...

  9. Java并发编程面试题 Top 50 整理版

    本文在 Java线程面试题 Top 50的基础上,对部分答案进行进行了整理和补充,问题答案主要来自<Java编程思想(第四版)>,<Java并发编程实战>和一些优秀的博客,当然 ...

随机推荐

  1. target属性用于返回最初触发事件的DOM元素。

    target属性用于返回最初触发事件的DOM元素. 在HTML文档中,我们为<p>元素绑定点击事件("click"),由于DOM元素的事件冒泡机制,我们点击<p& ...

  2. XAF-如何实现自定义权限系统用户对象

    本示例使用XPO. 新建一个XAF项目.填加两个类进来:   [DefaultClassOptions] public class Employee : Person { public Employe ...

  3. idea配置SOLServer错误解决记录

    1.错误信息:2019-03-26 13:32:41.205 ERROR 7828 --- [nio-8081-exec-1] c.alibaba.druid.filter.stat.StatFilt ...

  4. gitlab+jenkins持续集成(二)

    1.jenkins服务器上的配置 -bin.tar.gz -C /opt/ yum install -y git /conf/settings.xml #只需更改maven的地址 <?xml v ...

  5. 正则表达式的捕获组(Java)

    捕获组分类 普通捕获组(Expression) 命名捕获组(?<name>Expression) 普通捕获组 从正则表达式左侧开始,每出现一个左括号“(”记做一个分组,分组编号从1开始.0 ...

  6. GitHub笔记(五)——忽略文件、配置别名、搭建服务器

    六.忽略文件 忽略某些文件时,需要编写.gitignore: .gitignore文件本身要放到版本库里,并且可以对.gitignore做版本管理! 忽略文件的原则是: 忽略操作系统自动生成的文件,比 ...

  7. python编辑选课系统

    一.需求分析 1. 创建北京.上海 2 所学校 2. 创建linux , python , go 3个课程 , linux\py 在北京开, go 在上海开 3. 课程包含,周期,价格,通过学校创建课 ...

  8. Gitlab CI-2.CI流程

    参考文档: GitLab Documentation:https://docs.gitlab.com/ce/ Installation and Configuration using omnibus ...

  9. 服务端模版注入漏洞检测payload整理

    服务端模版注入漏洞产生的根源是将用户输入的数据被模版引擎解析渲染可能导致代码执行漏洞 下表涵盖了java,php,python,javascript语言中可能使用到的模版引擎,如果网站存在服务端模版注 ...

  10. NIO中的Buffer

    public abstract class Buffer { // Invariants: mark <= position <= limit <= capacity private ...