一、原子性操作

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. MySQL易忘知识点梳理

    一.零碎知识 1.mysql where子句区分大小写:WHERE BINARY 2.判断是否为null,只能用is null,is not null,不能用=null或!=null 3.函数 4.S ...

  2. java多线程的简单demo

    模拟场景:顾客买车从车库中取车,厂家生产车,车存储在车库中.买家.厂家对同一个车库中的车操作 一.不加同步机制的代码如下: package com.joysuch.testng.thread; imp ...

  3. anaconda 及python pip安装 类库等问题收集

    在win7下 通过anaconda安装jieba 报如下错误: 问题1:TypeError: parse() got an unexpected keyword argument 'transport ...

  4. 使用MUART0-P-1-2设置无线PM2.5感测环境

    信息搜集–> 处理分析–> 动作执行,这是IoT环境中最基本的组成要素,传感器搜集环境信息后,透过指定的通讯协议传送到至控制中枢,经过处理分析后再将命令送交各device端执行.要实现这样 ...

  5. 沧桑巨变中焕发青春活力-记极1s HC5661A 打怪升级之路

    最近发现一个新货umaxhosting年付10美元的便宜VPS.2杯喜茶的价格可以让你在国外拥有一个1024MB (1GB) DDR3 RAM.1024MB (1GB) vSwap.70GB RAID ...

  6. Linux入门基础(六):Linux系统启动

    系统启动流程 BIOS MBR : Boot Code 执行引导程序-GRUB 加载内核 执行init runlevel BIOS BIOS(basic input output system),我们 ...

  7. C/S结构与B/S结构

    按照是否需要访问网络,程序可分为网络程序与非网络程序.其中网络程序又可分为B/S结构与C/S结构. C/S结构是指客户端(Client)/服务器(Server)模式,这种模式的客户端中 需要安装一个R ...

  8. 比较undefined和“undefined”

    说实话,它们之间的区别挺明显的,我们一般认为undefined是JavaScript提供的一个“关键字”,而“undefined”却是一个字符串,只是引号的内容和undefined一样. undefi ...

  9. Netty源码分析第2章(NioEventLoop)---->第5节: 优化selector

    Netty源码分析第二章: NioEventLoop   第五节: 优化selector 在剖析selector轮询之前, 我们先讲解一下selector的创建过程 回顾之前的小节, 在创建NioEv ...

  10. kuberentes 源码编译安装

    下载源码 git clone https://github.com/kubernetes/kubernetes && cd kubernetes # 切换版本分支 git checko ...