多线程 | synchronized的简单使用

news2024/9/21 1:25:03

synchronized 关键字是 Java 中解决并发问题的一种常用方法,也是最简单的一种方法,其作用有三个:
(1)互斥性:确保线程互斥的访问同步代码
(2)可见性:保证共享变量的修改能够及时可见
(3)有序性:有效解决重排序问题, 其用法也有三个:

  1. 修饰实例方法
  2. 修饰静态方法
  3. 修饰代码块

修饰实例方法

public class SynchronizedInstanceMethod implements Runnable{
    //共享资源(临界资源)
    static int i=0;

    //如果没有synchronized关键字,输出小于20000
    public synchronized void increase(){
        i++;
    }
    public void run() {
        for(int j=0;j<10000;j++){
            increase();
        }
    }
    public static void main(String[] args) throws InterruptedException {
        Thread1 t=new Thread1();
        Thread t1=new Thread(t);
        Thread t2=new Thread(t);
        t1.start();
        t2.start();
        t1.join();//主线程等待t1执行完毕
        t2.join();//主线程等待t2执行完毕
        System.out.println(i);
    }
    /**
     * 输出结果:
     * 20000
     */
}

修饰静态方法

public class SynchronizedStaticMethod {
    //共享资源(临界资源)
    static int i = 0;

    //如果没有synchronized关键字,输出小于20000
    public static synchronized void increase() {
        i++;
    }

    public static void main(String[] args) throws InterruptedException {
        Thread t1 = new Thread(new Runnable() {
            public void run() {
                for (int j = 0; j < 10000; j++) {
                    increase();
                }
            }
        });
        Thread t2 = new Thread(new Runnable() {
            @Override
            public void run() {
                for (int j = 0; j < 10000; j++) {
                    increase();
                }
            }
        });
        t1.start();
        t2.start();
        t1.join();//主线程等待t1执行完毕
        t2.join();//主线程等待t2执行完毕
        System.out.println(i);
    }
    /**
     * 输出结果:
     * 20000
     */
}

修饰代码块

public class SynchronizedCodeBlock implements Runnable{
    //共享资源(临界资源)
    static int i=0;


    @Override
    public void run() {
        for(int j=0;j<10000;j++){
            //获得了String的类锁
            synchronized (String.class){
            i++;}
        }
    }
    public static void main(String[] args) throws InterruptedException {
        SynchronizedCodeBlock t=new SynchronizedCodeBlock();
        Thread t1=new Thread(t);
        Thread t2=new Thread(t);
        t1.start();
        t2.start();
        t1.join();
        t2.join();
        System.out.println(i);
    }
    /**
     * 输出结果:
     * 20000
     */
}

总结

  1. synchronized 修饰的实例方法,多线程并发访问时,只能有一个线程进入,获得对象内置锁,其他线程阻塞等待,但在此期间线程仍然可以访问其他方法。
  2. synchronized 修饰的静态方法,多线程并发访问时,只能有一个线程进入,获得类锁,其他线程阻塞等待,但在此期间线程仍然可以访问其他方法。
  3. synchronized 修饰的代码块,多线程并发访问时,只能有一个线程进入,根据括号中的对象或者是类,获得相应的对象内置锁或者是类锁
  4. 每个类都有一个类锁,类的每个对象也有一个内置锁,它们是互不干扰的,也就是说一个线程可以同时获得类锁和该类实例化对象的内置锁,当线程访问非 synchronzied 修饰的方法时,并不需要获得锁,因此不会产生阻塞。

当修饰静态方法的时候,锁定的是当前类的 Class 对象;当修饰非静态方法的时候,锁定的是当前实例对象 this。

class SafeCalc {
  static long value = 0L;
  synchronized long get() {
    return value;
  }
  synchronized static void addOne() {
    value += 1;
  }
}

受保护资源和锁之间的关联关系是 N:1 的关系。还拿前面球赛门票的管理来类比,就是一个座位,我们只能用一张票来保护,如果多发了重复的票,那就要打架了。现实世界里,我们可以用多把锁来保护同一个资源,但在并发领域是不行的,并发领域的锁和现实世界的锁不是完全匹配的。不过倒是可以用同一把锁来保护多个资源,这个对应到现实世界就是我们所谓的“包场”了。

上边代码中,value 改成静态变量,把 addOne() 方法改成静态方法,此时 get() 方法和 addOne() 方法是否存在并发问题呢?
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2107656.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

UOS系统通过Remmina远程windows系统桌面

windows系统之间可以互相进行远程桌面连接&#xff0c;那么UOS系统是否可以远程到windows系统桌面呢&#xff1f;请见下面的文章。 下载安装Remmina软件 首先我们需要在UOS系统上面找到应用商店&#xff0c;下载并安装一个Remmina软件 windows系统开启允许远程桌面连接 wind…

记录ssl epoll的tcp socket服务端在客户端断开时崩溃的问题

文章目录 当客户端关闭后&#xff0c;Epoll 的 TCP socket 服务端会收到两次断开事件可能有以下原因及解决方法&#xff1a;原因分析解决方法 问题ssl socket服务端代码出错现象第一次尝试修改正确改法附上客户端代码 记录ssl epoll的tcp socket服务端在客户端断开时接收到多次…

聚铭网络入选“2024年南京市工程研究中心”认定名单

为深入实施创新驱动发展战略&#xff0c;因地制宜发展新质生产力充分发挥工程研究中心对推进产业强市的重要支撑作用&#xff0c;根据《南京市工程研究中心管理办法》&#xff0c;南京市发展和改革委员会于2024年5月组织开展了本年度南京市工程研究中心遴选工作。经企业申报、各…

编译安装调试 scaLapack 和 openmpi 以及 lapack

编译安装调试 scaLapack /home/hipper/ex_scalapack/ mkdir ./lapack mkdir -p ./lapack/local/lib mkdir ./openmpi mkdir ./scalapack 1&#xff0c;编译安装 Lapack 下载代码&#xff1a; cd lapack wget https://github.com/Reference-LAPACK/lapack/archive/refs/tags/…

[全网首发]2024国赛数学建模ABCE题完整思路+py(matlab)代码+成品论文参考+持续更新

AB题详细思路(含问题一问题二模型) CE题问题一代码思路已经写好[pythonmatlab两种都会更新 需要完整版的看这里&#xff1a; 点击链接加入群聊【2024数学建模国赛资料汇总】&#xff1a;http://qm.qq.com/cgi-bin/qm/qr?_wv1027&klZncBILk30DuPRI1Bd8X-3Djv7ZVZyAv&…

【非零段划分 / 2】

题目 思路 第一种思路&#xff1a;按照表面题意&#xff0c;枚举p&#xff0c;处理数组后进行计数&#xff1a; 复杂度 ∈ O ( n ⋅ m ) 复杂度 \in O(n \cdot m) 复杂度∈O(n⋅m) 第二种思路&#xff1a;把数组看成一个二维的山形图&#xff0c;先将相邻的水平线段转化成点…

Java核心知识体系-并发与多线程:线程基础

1 先导 Java线程基础主要包含如下知识点&#xff0c;相信我们再面试的过程中&#xff0c;经常会遇到类似的提问。 1、线程有哪几种状态? 线程之间如何转变&#xff1f; 2、线程有哪几种实现方式? 各优缺点&#xff1f; 3、线程的基本操作&#xff08;线程管理机制&#xff…

数据资产入表元年,企业如何抓住数据资产增值的机遇?

近年来&#xff0c;政府将数据要素纳入了经济发展的重要指示性文件当中&#xff0c;希望利用数据驱动。《全国数据资源调查报告&#xff08;2023年&#xff09;》显示&#xff0c;2024年以来不少地方纷纷成立“数据集团”&#xff0c;加快盘活数据资产。作为数字经济时代的首要…

Java | Leetcode Java题解之第389题找不同

题目&#xff1a; 题解&#xff1a; class Solution {public char findTheDifference(String s, String t) {int ret 0;for (int i 0; i < s.length(); i) {ret ^ s.charAt(i);}for (int i 0; i < t.length(); i) {ret ^ t.charAt(i);}return (char) ret;} }

编写Dockerfile第二版

目标 更快的构建速度 更小的Docker镜像大小 更少的Docker镜像层 充分利用镜像缓存 增加Dockerfile可读性 让Docker容器使用起来更简单 总结 编写.dockerignore文件 容器只运行单个应用 将多个RUN指令合并为一个 基础镜像的标签不要用latest 每个RUN指令后删除多余文…

leetcode172. 阶乘后的零,遍历每个因数中5的个数

leetcode172. 阶乘后的零 给定一个整数 n &#xff0c;返回 n! 结果中尾随零的数量。 提示 n! n * (n - 1) * (n - 2) * … * 3 * 2 * 1 示例 1&#xff1a; 输入&#xff1a;n 3 输出&#xff1a;0 解释&#xff1a;3! 6 &#xff0c;不含尾随 0 示例 2&#xff1a; 输…

第八届控制工程与先进算法国际论坛(IWCEAA 2024)

重要信息 会议大会官网&#xff1a;www.iwaace.cn&#xff08;点击进一步了解&#xff09; 二轮截稿时间&#xff1a;2024年09月27日 录用通知时间&#xff1a;投稿后7个工作日 收录检索类型&#xff1a;IEEE Xplore, EI, Scopus 大会介绍 第八届控制工程与先进算法国际论…

python 交互模式怎么切换目录

假如要用交互界面调用一个.py文件&#xff1a; &#xff08;1&#xff09;用cmd界面定位到文件位置&#xff0c;如cd Desktop/data/ #进入desktop下data目录。 &#xff08;2&#xff09;接着打开python&#xff08;输入python&#xff09; 调用os &#xff08;1&#xff0…

3.js - modelPosition.z = sin((modelPosition.x+uTime)*10.0)*0.05;

哈 1、完整的动态波纹效果吧 main.js import * as THREE from three import { OrbitControls } from three/examples/jsm/controls/OrbitControls// 顶点着色器 import basicVertexShader from ./shader/11-01/raw/vertex.glsl?raw // 片元着色器 import basicFragmentShad…

python OpenGL绘制正八面体代码

学习OpenGL过程中&#xff0c;先从绘制三角形开始逐渐对Opengl有一些了解&#xff0c;到现在进阶到绘制立方体。通过借鉴网友绘制六面体得到灵感&#xff0c;改了一下他的代码成功绘制出正八面体。不管是绘制三角形还是绘制立方体&#xff0c;对于空间坐标系要相当熟悉&#xf…

苍穹外卖项目前端DAY03

前端DAY03 1、套餐管理 1.1、套餐分页查询 1.1.1、需求分析和接口设计 产品原型&#xff1a; 业务规则&#xff1a; 根据页码展示套餐信息每页展示10条数据分页查询时可以根据需要&#xff0c;输入套餐名称、套餐分类、售卖状态进行查询 接口设计&#xff1a; 套餐分页查…

如何使用电商API接口?(淘宝|京东商品详情数据接口)

一、了解电商API接口&#xff1a; 如今&#xff0c;在电商市场中&#xff0c;电商API接口的广泛应用极大地提高了电商行业的工作效率&#xff0c;使得商家能够灵活集成多种服务&#xff0c;高效优化业务流程。 当前&#xff0c;电商平台中的多种业务都可以通过使用API接口来做…

Tomato靶场渗透测试

1.扫描靶机地址 可以使用nmap进行扫描 由于我这已经知道靶机地址 这里就不扫描了 2.打开网站 3.进行目录扫描 dirb http&#xff1a;//172.16.1.113 发现有一个antibot_image目录 4.访问这个目录 可以看到有一个info.php 5.查看页面源代码 可以发现可以进行get传参 6.…

脉脉高聘:大模型算法岗平均月薪近7万元,位居高薪榜第一

9月5日&#xff0c;脉脉高聘人才智库数据显示&#xff0c;大模型领域整体供需比1.76&#xff0c;整体供大于求。同时&#xff0c;高技术岗位人才稀缺&#xff0c;云计算人才供需比仅为0.33&#xff0c;相当于3个岗位争夺1个人才。大模型算法岗位平均月薪最高&#xff0c;超过6.…

【STM32+HAL库】---- 驱动MAX30102心率血氧传感器

硬件开发板&#xff1a;STM32F407VET6 软件平台&#xff1a;cubemaxkeilVScode1 MAX30102心率血氧传感器工作原理 MAX30102传感器是一种集成了红外光源、光电检测器和信号处理电路的高度集成传感器&#xff0c;主要用于心率和血氧饱和度的测量。以下是MAX30102传感器的主要特点…