java高并发、多线程(三)--synchronized

JAVA的多线程与高并发 概念 进程 进程指正在运行的程序,进程拥有一个完整的、私有的基本运行资源集合。通常,每个进程都有自己的内存空间。 进程往往被看作是程序或应用的代名词,然而,用户看到的一个单独的应用程序实际上可能是一组相互 协作的进程集合。 为了便于进程之间的通信,大多数操作系统都支持进程间通信(IPC),如pipes 和sockets。IPC不仅支持同一系统上的通信,也支持不同的系统。IPC通信方式包括管道(包括无名管道和命名管道)、消息队列、信号量、共享存储、Socket、Streams等方式,其中 Socket 阅读详情

synchronized

先看下面例子:

public class SynchronizedTest {
    static int count = 0;
    public static void add() {
        for (int i = 0; i < 10000; i++) {
            count++;
        }
    }

    public static void main(String[] args) {
        List<Thread> list = new ArrayList<>();
        for (int i = 0; i < 10; i++) {
            list.add(new Thread(SynchronizedTest::add,"Thread-"+i));
        }
        list.forEach(t->t.start());
        list.forEach(t-> {
            try {
                t.join();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        });
        System.out.println(count);
    }
}

运行结果:
在这里插入图片描述
以上代码开启10个线程对count进行累加10000次,我们希望的结果是10万,但是最终结果是小于等于10万的。这是由于count++这个操作并不是原子操作,代码产生了同步问题,我们可以给相关代码加上锁来解决上面的问题。

加锁的方式

  • 同步代码块上加锁
	private static Object object = new Object();
    public static void add() {
        for (int i = 0; i < 10000; i++) {
            synchronized (object){
                count++;
            }
        }
    }
  • 方法上加锁
    public synchronized static void add() {
        for (int i = 0; i < 10000; i++) {
                count++;
        }
    }

运行结果:
在这里插入图片描述

synchronized的性质

  • 保证线程间可见性
	static int count = 0;

我们可以观察到上述代码中,我们并没有给count变量采用volatile修饰,但是程序的运行结果是正确的,那么说明synchronized可以替代volatile,能够保证线程间的可见性。

那volatile可以替代synchronized吗?
我们对上述代码做如下修改:

	volatile static int count = 0;
    public /*synchronized*/ static void add() {
        for (int i = 0; i < 10000; i++) {
                count++;
        }
    }

运行结果:
在这里插入图片描述
由运行结果可知:volatile并不能替代synchronized的作用,它不能保证多个线程共同修改共享变量所带来的不一致问题。

  • synchronized获得的是重入锁
    修改上述代码:
	static int count = 0;
    public synchronized static void add() {
        for (int i = 0; i < 10000; i++) {
                count++;
        }
        //调用另一个同步方法
        sub();
    }
    public synchronized static void sub() {
        for (int i = 0; i < 10000; i++) {
            count--;
        }
    }

运行结果:
在这里插入图片描述
从运行结果可以知道,一个同步方法可以调用另一个同步方法。

synchronized锁升级

偏向锁
自旋锁
重量级锁

优化

  • 采用细粒度的锁,减少同步代码块中代码量

注意事项

  • 不使用字符串作为锁对象
    例如:
public class SynchronizedTest {

    String lock1 = "lock";
    String lock2 = "lock";

    public void m1(){
        synchronized (lock1){
            System.out.println("m1 start");
            while(true){}
        }
    }
    public void m2(){
        synchronized (lock2){
            System.out.println("m2 start");
            while(true){}
        }
    }

    public static void main(String[] args) {
        SynchronizedTest st = new SynchronizedTest();
        new Thread(st::m1).start();
        new Thread(st::m2).start();
    }
}

运行结果:
在这里插入图片描述
由上面的例子可以看出:代码原意是想m1与m2方法获取不同的锁,但是由于string常量池的性质,导致两把锁实际上指向的是同一个对象,从而m1与m2方法仅能执行其中的一个。

  • 不要改变锁的引用
    例如:
public class SynchronizedTest {

    private Object o = new Object();

    public void m1(){
        synchronized (o){
            System.out.println("m1 start");
            while(true){}
        }
    }
    public void m2(){
        synchronized (o){
            System.out.println("m2 start");
            while(true){}
        }
    }

    public static void main(String[] args) {
        SynchronizedTest st = new SynchronizedTest();
        new Thread(st::m1).start();
        try {
            Thread.sleep(1000);
            //改变o指向的对象
            st.o = new Object();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        new Thread(st::m2).start();
    }
}

运行结果:
在这里插入图片描述
从这个例子可以看出,当改变了锁对象的引用后m2方法可以得到执行。因此锁对象建议加上final关键字修饰

	private final Object o = new Object();
【Java面试并发多线程】Synchronized锁的讲解 在我们和面试官吹多线程的时候,我们务必会涉及到锁的问题,这就需要我们死磕并发并深入剖析synchronized底层原理了,希望可以帮到你,哈哈~~ 1.面试经验: 面试官问你,你有没有接触过多线程的问题 复习的不错的朋友可以说:有接触到,在项目中因为一些业务,哪哪有使过多线程,怎么使用的,然后再去深入讲解多线程知识。 如果你之前只是粗略的学习过多线程,面试初级开发的话,你可以这样回答:因为项目的限制,很少使用多线程,但是多线程怎么使用还是会的,也做过一些窗口卖票的多线程小案例。 2.线程的并发问题: 在 阅读详情

相关推荐

Java多线程——synchronized,volatile,CAS,ReentrantLock

当没有线程占用锁对象时处于无锁,当有一个线程占用该锁时变成偏向锁,偏向搜不是真的加锁,而是添加一种锁标记,如果之后没有发生锁竞争就无须开销锁资源,如果有锁竞争就添加自旋锁,自旋锁是一种轻量级锁,在锁冲突不激烈的情况下,在抢占不到锁时不会处于阻塞状态而会一致尝试抢占锁,当锁竞争激烈时,自旋锁不能马上获取到锁,就会膨胀为重量级锁,调用OS的mutex将没有抢占到锁的线程加入到阻塞队列中,重量级锁的具体执行过程如上述介绍。.lock前缀指令在多核处理器中会做2件事情:将当前工作内存中的变量的值写回到主内存中;

weixin_52477733的博客 718

Java synchronized代码块锁字符串无效的问题解决方案

Java synchronized代码块锁字符串无效的问题解决方案 //test测试方法,直接锁住字符串,是没有效果的,因为synchronized(str)相当于重新new String(str)一个字符串作为锁住的参数,每个对象的hashcode不同,所以没有效果。 public static void test(String str) { synchronized(str) { System.out.println("进来啦" + str); try { Thread.sl

lluohuih的专栏 1664

【Java多线程】内置锁(Synchronized)的前世今生

**Java内置锁不需要显式的获取锁和释放锁,由JVM内部来实现锁的获取与释放。而且任何一个对象都能作为一把内置锁。在`JDK1.4`及之前就是使用`内置锁Synchronized`来进行线程同步控制的** `上文说,任何一个对象都能作为一把内置锁”,意味着synchronized关键字出现的地方,都有一个对象与之关联`,具体表现为: - 当synchronized作用于`普通方法`时,锁对象是`this`; - 当synchronized作用于`静态方法`时,锁对象是`当前类的Class对象`; -

墩墩分墩 3764

如何通过Java中的对象值来同步块

问题 有时,我们需要通过变量的值来同步代码块。 为了解这个问题,我们将考虑一个简单的银行应用程序,它对客户的每次转账进行以下操作: 通过此外部Web服务转移评估现金返还金额(CashBackService) 在数据库中执行汇款(AccountService) 更新现金返还评估系统中的数据(CashBackService) 汇款操作如下: public void withdrawM...

Tybyqi的博客 1033

用Python实现斗地主游戏(终端版)

马上就要过年了 大家也都放假了吧 过年必不可少的活动 打牌! 今天带大家来写一份斗地主 (又是好多天没怎么更新,忙成狗啊) 那么实现一个斗地主呢 我们肯定要先完善卡牌系统 from collections import Counter import numpy as np import itertools def cmp_to_key(mycmp): 'Convert a cmp= function into a key= function' class K: def _

Miku_wx的博客 9856

手把手教你用CMake和MinGW64编译libuvc:静态链接与动态链接的选择

本文详细指导如何在Windows平台上使用CMake和MinGW64编译libuvc库,并深入探讨静态链接与动态链接的选择策略。通过对比两种链接方式在部署复杂度、内存占用和版本管理等方面的差异,帮助开发者根据项目需求做出最优决策,实现高效的USB摄像头开发。

weixin_29171087的博客 255

java并发基础-Synchronized

基础使用 基本上Java程序员都简单的了解synchronized的使用: 无非就是用在多线程环境下的同步。 看如下简单的例子: publicclassUnsafeCounter{ privateint count=0; publicint getAndIncrement(){ returnthis.count++; } }    上面是一个简单的非常常见的...

216

从Wi-Fi到蓝牙:手把手教你用Cadence Virtuoso搭建一个2.4GHz锁相环频率综合器(含PFD/CP/VCO模块设计)

本文详细介绍了如何在Cadence Virtuoso中设计一个2.4GHz锁相环频率综合器(PLL),涵盖从系统架构到模块级设计的全流程。重点解析了PFD、CP和VCO等核心模块的设计技巧与仿真验证方法,帮助模拟集成电路设计师掌握高频PLL的实现要点,满足Wi-Fi和蓝牙等无线通信标准的要求。

weixin_30315723的博客 418

【Java】多线程和高并发编程(三):锁(上)锁的分类、深入synchronized

偏向锁在升级为轻量级锁时,会涉及到偏向锁撤销,需要等到一个安全点(STW),才可以做偏向锁撤销,在明知道有并发情况,就可以选择不开启偏向锁,或者是设置偏向锁延迟开启。:如果在一个循环中,频繁的获取和释放做资源,这样带来的消耗很大,锁膨胀就是将锁的范围扩大,避免频繁的竞争和获取锁资源带来不必要的消耗。:当前线程获取到A锁,在获取之后尝试再次获取A锁,无法获取到的,因为A锁被当前线程占用着,需要等待自己释放锁再获取锁。:线程A获取到了锁资源,线程B没有拿到,线程B去排队,线程C来了,先尝试竞争一波。

专注上位机开发、机器视觉、机器学习、嵌入式软硬件开发 1万+

SAP ERPsim生产拓展实验报告

ERP课的实验和实践,也是SAP竞赛玩的东西,除了界面不华丽外很像游戏而且是团队型的pvp大乱斗

m0_67262022的博客 2020

iOS自动化之打包-xcodebuild命令行打包.app并安装到ios模拟器

xcode xcodebuild xcrun ios模拟器 iOS UI自动化测试 ios自动打包安装到ios模拟器

z12347891的博客 5074

java多线程和高并发系列三 & Synchronized锁详解

java多线程和高并发系列三 & Synchronized锁详解 偏向锁 轻量级锁 自旋锁 重量级锁

weixin_37552984的博客 662

【温室气体数据集】CAMS 发布的温室气体(GHG)数据集总结

【温室气体数据集】CAMS 发布的温室气体(GHG)数据集总结

WW、forever的博客 555

多线程与高并发

进程是操作系统进行资源分配的基本单位Java 内存模型规定所有的共享变量都是存在主存当中(类似于前面说的物理内存),每个线程都有自己的工作内存(比如CPU的高速缓存)。线程对变量的所有操作都必须在工作内存中进行,而不能直接对主存进行操作,并且每个线程不能访问其他线程的工作内存。之所以要用自己的本地内存,主要是利用缓存和改变执行代码顺序达到程序执行效率优化。

2304_80073016的博客 633

一文吃透 Tools for Applying SAP Notes:从 SNOTE、TCI 到 Solution Manager 与 SAP Cloud ALM

本文系统梳理了SAP技术与运维团队应用SAP Notes的高效工具与方法,涵盖On-Premise与云环境。文章首先阐述了精研SAP Notes工具的必要性,指出其是实施错误修复、法务变更和性能改进的关键载体。随后详细介绍了SNOTE、TCI、Solution Manager、Cloud ALM和Maintenance Planner等核心工具的定位与适用场景,并通过采购异常案例展示了标准更正流程。针对复杂修复场景,文章提出了TCI的批量处理方案,并强调将Note实施纳入变更治理流程的重要性。最后总结了三种

2007 年 ~ 2025 年,深耕 SAP 技术 18 年 354

计算机控制技术及应用

《计算机控制技术及应用》通过总结作者的科研成果和吸收国内外的先进理论、方法和技术,以计算机控制系统的网络化、开放化、智能化和集成化发展趋势为主线索,主要介绍计算机控制系统的基本概念和计算机控制系统的典型形式,计算机控制系统的数学描述与基本分析方法,以及数字PID控制器、最少拍控制系统、达林算法、状态变量设计法等设计方法及其各种改进算法。重点突出计算机控制系统输入输出通道接口的设计方法和典型控制系统的设计案例与实现方法等。

Java多线程与高并发

当谈到计算机数据存储和传输时,我们使用位(bit)和字节(byte)来表示不同的数据量。一个位代表一个二进制数字,可以是0或1。而一个字节由8个位组成,可以表示256种不同的状态。字节是计算机中最常用的存储单位,用于表示字符、整数、图像等各种数据类型。在Java开发中,字节和位的关系非常重要。Java中的基本数据类型(如int、char)都占用特定数量的字节,以对应不同范围的数值。例如,int类型占用4个字节,可以表示范围更大的整数值。理解字节和位的关系对于编写高效的程序至关重要。

1468

VB摄像头监控

该VB模块可对摄像头捕获的画面进行录像等,可在创建的窗口进行控制

【Java 多线程】Synchronized

偏向锁状态下,线程要获取锁时,会在 MarkWord 中直接记录线程 ID,只要线程来执行代码了,会对比线程 ID 是否相等,相等直接获取锁,执行同步代码,不相等则尝试使用 CAS 修改 MarkWord 中的线程 ID ,如果修改成功则获取锁,修改不成功说明有竞争,因此会撤销偏向锁升级为轻量级锁。在内存中,对象一般由三部分组成,分别是对象头、实际数据和对齐填充,重点在与对象头,对象头中有一个我们比较关注的部分,MarkWord,MarkWord 中记录了有关锁的信息包括锁标记位,是否为偏向锁等。

栗子的博客 2252

温度PID控制PLC程序

温度PID稳定控制程序,适用于欧姆龙PLC,对其他PLC也具有很大参考价值

深度学习工具包 DeepLearningToolbox

深度学习工具包Deprecation notice.-----This toolbox is outdated and no longer maintained.There are much better tools available for deep learning than this toolbox, e.g. [Theano](http://deeplearning.net/software/theano/), [torch](http://torch.ch/) or [tensorflow](http://www.tensorflow.org/)I would suggest you use one of the tools mentioned above rather than use this toolbox.Best, Rasmus.DeepLearnToolbox================A Matlab toolbox for Deep Learning.Deep Learning is a new subfield of machine learning that focuses on learning deep hierarchical models of data.It is inspired by the human brain's apparent deep (layered, hierarchical) architecture.A good overview of the theory of Deep Learning theory is[Learning Deep Architectures for AI](http://www.iro.umontreal.ca/~bengioy/papers/ftml_book.pdf)For a more informal introduction, see the following videos by Geoffrey Hinton and Andrew Ng.* [The Next Generation of Neural Networks](http://www.youtube.com/watch?v=AyzOUbkUf3M) (Hinton, 2007)* [Recent Developments in Deep Learning](http://www.youtube.com/watch?v=VdIURAu1-aU) (Hinton, 2010)* [Unsupervised Feature Learning and Deep Learning](http://www.youtube.com/watch?v=ZmNOAtZIgIk) (Ng, 2011)If you use this toolbox in your research please cite [Prediction as a candidate for learning deep hierarchical models of data](http://www2.imm.dtu.dk/pubdb/views/publication_details.php?id=6284)```@MASTERSTHESIS\{IMM2012-06284, author = "R. B. Palm", title = "Prediction as a candidate for learning deep hierarchical models of data", year = "2012",}```Contact: rasmusbergpalm at gmail dot comDirectories included in the toolbox-----------------------------------`NN/` - A library for Feedforward Backpropagation Neural Networks`CNN/` - A library for Convolutional Neural Networks`DBN/` - A library for Deep Belief Networks`SAE/` - A library for Stacked Auto-Encoders`CAE/` - A library for Convolutional Auto-Encoders`util/` - Utility functions used by the libraries`data/` - Data used by the examples`tests/` - unit tests to verify toolbox is workingFor references on each library check REFS.mdSetup-----1. Download.2. addpath(genpath('DeepLearnToolbox'));Example: Deep Belief Network---------------------```matlabfunction test_example_DBNload mnist_uint8;train_x = double(train_x) / 255;test_x = double(test_x) / 255;train_y = double(train_y);test_y = double(test_y);%% ex1 train a 100 hidden unit RBM and visualize its weightsrand('state',0)dbn.sizes = [100];opts.numepochs = 1;opts.batchsize = 100;opts.momentum = 0;opts.alpha = 1;dbn = dbnsetup(dbn, train_x, opts);dbn = dbntrain(dbn, train_x, opts);figure; visualize(dbn.rbm{1}.W'); % Visualize the RBM weights%% ex2 train a 100-100 hidden unit DBN and use its weights to initialize a NNrand('state',0)%train dbndbn.sizes = [100 100];opts.numepochs = 1;opts.batchsize = 100;opts.momentum = 0;opts.alpha = 1;dbn = dbnsetup(dbn, train_x, opts);dbn = dbntrain(dbn, train_x, opts);%unfold dbn to nnnn = dbnunfoldtonn(dbn, 10);nn.activation_function = 'sigm';%train nnopts.numepochs = 1;opts.batchsize = 100;nn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.10, 'Too big error');```Example: Stacked Auto-Encoders---------------------```matlabfunction test_example_SAEload mnist_uint8;train_x = double(train_x)/255;test_x = double(test_x)/255;train_y = double(train_y);test_y = double(test_y);%% ex1 train a 100 hidden unit SDAE and use it to initialize a FFNN% Setup and train a stacked denoising autoencoder (SDAE)rand('state',0)sae = saesetup([784 100]);sae.ae{1}.activation_function = 'sigm';sae.ae{1}.learningRate = 1;sae.ae{1}.inputZeroMaskedFraction = 0.5;opts.numepochs = 1;opts.batchsize = 100;sae = saetrain(sae, train_x, opts);visualize(sae.ae{1}.W{1}(:,2:end)')% Use the SDAE to initialize a FFNNnn = nnsetup([784 100 10]);nn.activation_function = 'sigm';nn.learningRate = 1;nn.W{1} = sae.ae{1}.W{1};% Train the FFNNopts.numepochs = 1;opts.batchsize = 100;nn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.16, 'Too big error');```Example: Convolutional Neural Nets---------------------```matlabfunction test_example_CNNload mnist_uint8;train_x = double(reshape(train_x',28,28,60000))/255;test_x = double(reshape(test_x',28,28,10000))/255;train_y = double(train_y');test_y = double(test_y');%% ex1 Train a 6c-2s-12c-2s Convolutional neural network %will run 1 epoch in about 200 second and get around 11% error. %With 100 epochs you'll get around 1.2% errorrand('state',0)cnn.layers = { struct('type', 'i') %input layer struct('type', 'c', 'outputmaps', 6, 'kernelsize', 5) %convolution layer struct('type', 's', 'scale', 2) %sub sampling layer struct('type', 'c', 'outputmaps', 12, 'kernelsize', 5) %convolution layer struct('type', 's', 'scale', 2) %subsampling layer};cnn = cnnsetup(cnn, train_x, train_y);opts.alpha = 1;opts.batchsize = 50;opts.numepochs = 1;cnn = cnntrain(cnn, train_x, train_y, opts);[er, bad] = cnntest(cnn, test_x, test_y);%plot mean squared errorfigure; plot(cnn.rL);assert(er<0.12, 'Too big error');```Example: Neural Networks---------------------```matlabfunction test_example_NNload mnist_uint8;train_x = double(train_x) / 255;test_x = double(test_x) / 255;train_y = double(train_y);test_y = double(test_y);% normalize[train_x, mu, sigma] = zscore(train_x);test_x = normalize(test_x, mu, sigma);%% ex1 vanilla neural netrand('state',0)nn = nnsetup([784 100 10]);opts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samples[nn, L] = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.08, 'Too big error');%% ex2 neural net with L2 weight decayrand('state',0)nn = nnsetup([784 100 10]);nn.weightPenaltyL2 = 1e-4; % L2 weight decayopts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex3 neural net with dropoutrand('state',0)nn = nnsetup([784 100 10]);nn.dropoutFraction = 0.5; % Dropout fraction opts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex4 neural net with sigmoid activation functionrand('state',0)nn = nnsetup([784 100 10]);nn.activation_function = 'sigm'; % Sigmoid activation functionnn.learningRate = 1; % Sigm require a lower learning rateopts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex5 plotting functionalityrand('state',0)nn = nnsetup([784 20 10]);opts.numepochs = 5; % Number of full sweeps through datann.output = 'softmax'; % use softmax outputopts.batchsize = 1000; % Take a mean gradient step over this many samplesopts.plot = 1; % enable plottingnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex6 neural net with sigmoid activation and plotting of validation and training error% split training data into training and validation datavx = train_x(1:10000,:);tx = train_x(10001:end,:);vy = train_y(1:10000,:);ty = train_y(10001:end,:);rand('state',0)nn = nnsetup([784 20 10]); nn.output = 'softmax'; % use softmax outputopts.numepochs = 5; % Number of full sweeps through dataopts.batchsize = 1000; % Take a mean gradient step over this many samplesopts.plot = 1; % enable plottingnn = nntrain(nn, tx, ty, opts, vx, vy); % nntrain takes validation set as last two arguments (optionally)[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');```[![Bitdeli Badge](https://d2weczhvl823v0.cloudfront.net/rasmusbergpalm/deeplearntoolbox/trend.png)](https://bitdeli.com/free "Bitdeli Badge")

Java多线程——synchronized关键字

虽然说synchronized已经优化了很多,但是了lock 还是存在一定差距的在性能上来说,如果竞争资源不激烈,两者的性能是差不多的,而当竞争资源非常激烈时(即有大量线程同时竞争),此时Lock的性能要远远优于synchronized。所有的Java对象是天生的Monitor,每一个Java对象都有成为Monitor的潜质,因为在Java的设计中,每一个Java对象自打娘胎里出来就带了一把看不见的锁,它叫做内部锁或者Monitor锁。

jcc4261的博客 1007

java多线程之synchronized详解

通过4问题,我们可以看到,通常情况下,为了保证多线程间的有效并发, 会要求每个线程持有锁的时间尽可能短,但是大某些情况下,一个程序对同一个锁不间断、高频地请求、同步与释放, 会消耗掉一定的系统资源,因为锁的讲求、同步与释放本身会带来性能损耗, 这样高频的锁请求就反而不利于系统性能的优化了,虽然单次同步操作的时间可能很短。每个对象都有一个监视器。当锁处于偏向锁状态后,这时出现了一个搅局者,被另外的线程访问了,这时偏向锁就会升级为轻量级锁,其他线程会通过自旋的形式尝试获取锁,但是不会阻塞,从而提高了性能。

qq_43022896的博客 1305

java多线程(三)Synchronized

一、Synchronized 使用 多线程的情况下对共享变量的访问必须进行同步处理,否则会出现意想不到的结果。Synchronized关键字就是进行多线程同步用的。 Synchronized的作用主要有三个:(1)确保线程互斥的访问同步代码(2)保证共享变量的修改能够及时可见(3)有效解决重排序问题。从语法上讲,Synchronized总共有三种用法:   (1)修饰普通方法

BNMB888的博客 429

多线程与高并发(2)——synchronized用法详解

这篇文章主要总结synchronized的用法,考虑到篇幅和方便自己记忆,synchronized的原理会在下篇文章详细总结。 一、定义 Synchronized是Java中常用的一个关键字。 Synchronized的作用主要有三个: (1)确保线程互斥的访问同步代码。——原子性 (2)保证共享变量的修改能够及时可见。——可见性 (3)有效解决重排序问题。——有序性 二、基础理论 这里只总结几大特性的基础理论,会在后续文章中陆陆续续结合关键字或者实例来讲解下面的特性。 1、共享性 在多线程编程中,数据共享

liwangcuihua的博客 1398

多线程与高并发系列二(Synchronized和volatile)

多线程与高并发系列二(Synchronized) synchronized关键字解决的是多个线程之间访问资源的同步性,synchronized关键字可以保证被它修饰的方法或者代码块在任意时刻只能有⼀个线程执行。

一只小菜鸡的博客 800

Java多线程与高并发专题——深入synchronized

Java多线程与高并发专题——深入synchronized

从知识输入到知识输出 994
上一篇: java高并发、多线程(二)--volatile
下一篇: java高并发、多线程(四)--AtomicInteger
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值