• Synchronized代码详解?


    synchronized是java的关键字,他有以下特性。

    互斥性:同一个时间只允许一个线程获取到某个对象锁,这样就可以保证线程安全,同一时间只有一个线程可以对代码进行访问操作。互斥性也就是我们经常说的原子性

    可见性:必须保证在锁被释放前,对数据的修改 对其他线程是可见的,否则其他线程从其他地方获取数据导致不一致性。

    synchronized是隐式锁,是jvm内置锁,不需要手动加锁与解锁,jvm会自动加锁跟解锁。

    而lock则需要实现lock接口,需要手动加锁和解锁。

    下面代码实例从三个方面进行加锁。

    1. 静态方法,锁的是类对象。
    2. 普通方法,锁的是实例对象。

    (需要注意:在spring容器中,bean是单实例,否则加synchronized没什么意义)

    1. 代码块:锁的是括号里的对象。
    1. /**
    2. * @author keying
    3. */
    4. public class Synchronized822 {
    5. public static void main(String[] args) throws InterruptedException {
    6. ThreadTestNei threadTestNei = new ThreadTestNei();
    7. ThreadA threadA = new ThreadA(threadTestNei);
    8. threadA.setName("A-THREAD");
    9. threadA.start();
    10. ThreadB threadB = new ThreadB(threadTestNei);
    11. threadB.setName("B-THREAD");
    12. threadB.start();
    13. }
    14. }
    15. class ThreadA extends Thread {
    16. private ThreadTestNei threadTestNei;
    17. ThreadA(ThreadTestNei threadTestNei) {
    18. this.threadTestNei = threadTestNei;
    19. }
    20. @Override
    21. public void run() {
    22. super.run();
    23. threadTestNei.setUser();
    24. }
    25. }
    26. class ThreadB extends Thread {
    27. private ThreadTestNei threadTestNei;
    28. ThreadB(ThreadTestNei threadTestNei) {
    29. this.threadTestNei = threadTestNei;
    30. }
    31. @Override
    32. public void run() {
    33. super.run();
    34. threadTestNei.setUser();
    35. }
    36. }
    37. @Data
    38. class ThreadTestNei {
    39. private String name;
    40. private String aString = new String();
    41. public void setUser() {
    42. try {
    43. synchronized (aString) {
    44. System.out.println(Thread.currentThread().getName() + "----" + "begin");
    45. Thread.sleep(1000);
    46. System.out.println(Thread.currentThread().getName() + "----" + "end");
    47. }
    48. } catch (Exception e) {
    49. }
    50. }
    51. }

    这时候他们修饰的是同一个对象,所以 输出是

    1. A-THREAD----begin
    2. A-THREAD----end
    3. B-THREAD----begin
    4. B-THREAD----end

    当代码改为

    1. try {
    2. String aString = new String();
    3. synchronized (aString) {
    4. System.out.println(Thread.currentThread().getName() + "----" + "begin");
    5. Thread.sleep(1000);
    6. System.out.println(Thread.currentThread().getName() + "----" + "end");
    7. }
    8. } catch (Exception e) {
    9. }

    输出则是:

    1. A-THREAD----begin
    2. B-THREAD----begin
    3. A-THREAD----end
    4. B-THREAD----end
    1. try {
    2. synchronized (ThreadTestNei.class) {
    3. System.out.println(Thread.currentThread().getName() + "----" + "begin");
    4. Thread.sleep(1000);
    5. System.out.println(Thread.currentThread().getName() + "----" + "end");
    6. }
    7. } catch (Exception e) {
    8. }

    如果锁住的是类,则输出的是

    1. A-THREAD----begin
    2. A-THREAD----end
    3. B-THREAD----begin
    4. B-THREAD----end

  • 相关阅读:
    Kubernetes教程(五)---Service 的几种访问方式
    golang pprof监控系列(2) —— memory,block,mutex 使用
    Spring 对于事务上的应用的详细说明
    浅谈安防视频监控平台EasyCVR视频汇聚平台对于夏季可视化智能溺水安全告警平台的重要性
    Gartner发布2022-2023年八大网络安全趋势预测,零信任是起点,法规覆盖更广
    2023年亚太杯数学建模亚太赛C题思路解析+代码+论文
    索引!索引!!索引!!!到底什么是索引?
    Git同时配置Gitee和GitHub
    Python中的ThreadPoolExecutor
    AOP是什么?如何使用AOP?
  • 原文地址:https://blog.csdn.net/ke1ying/article/details/126473372