zoukankan      html  css  js  c++  java
  • Java重温学习笔记,synchronized初步知识

    一、问题的提出,先看下面代码的输出

    public class MyDemo implements Runnable {
        private static int myCount = 0;
     
        public static void main(String[] args) {
            for (int i = 0; i < 10; i++) {
                Thread thread = new Thread(new MyDemo());
                thread.start();
            }
            try {
                Thread.sleep(500);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("result: " + myCount);
        }
        
        @Override // 此标签指明此方法覆盖父类同名方法。优点是编译器会帮你检查父类是否有同名方法,如没有则报错。
        public void run() {
             for (int i = 0; i < 100000; i++)   { 
                 myCount++;
            }
        }
    }

    不管你怎样运行,它的结果不会是10*100000。这是因为在线程在运行过程中,若干线程同时修改myCount类变量,程序没有解决多线程访问共享数据的问题。synchronized就是实现每个线程依次排队操作共享数据的功能。

    二、synchronized的使用场景,可以是方法,也可以是代码块

    三、下面是修改后的代码

    方法1. 代码块锁定。因为myCount是类变量,所以需要对类进行锁定

    public class MyDemo implements Runnable {
        private static int myCount = 0;
     
        public static void main(String[] args) {
            for (int i = 0; i < 10; i++) {
                Thread thread = new Thread(new MyDemo());
                thread.start();
            }
            try {
                Thread.sleep(500);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("result: " + myCount);
        }
        
        @Override // 此标签指明此方法覆盖父类同名方法。优点是编译器会帮你检查父类是否有同名方法,如没有则报错。
        public void run() {
             for (int i = 0; i < 100000; i++)   { 
                 synchronized (MyDemo.class) {
                     myCount++;
                 }
            }
        }
    }

    运行结果如下:

    %JAVA_HOME%injava "MyDemo" ...
    result: 1000000

     方法2:方法锁定。把同步代码独立出来,如下:

    public class MyDemo implements Runnable {
        private static int myCount = 0;
     
        public static void main(String[] args) {
            for (int i = 0; i < 10; i++) {
                Thread thread = new Thread(new MyDemo());
                thread.start();
            }
            try {
                Thread.sleep(500);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("result: " + myCount);
        }
        
        // synchronized修饰静态方法
        public synchronized static void method1() {
            myCount++;
        }
    
        @Override // 此标签指明此方法覆盖父类同名方法。优点是编译器会帮你检查父类是否有同名方法,如没有则报错。
        public void run() {
             for (int i = 0; i < 100000; i++)   { 
                 method1();
            }
        }
    }

    它的运行结果与上面是一样的。

    本文章参考:https://www.cnblogs.com/wangwudi/p/12302668.html

  • 相关阅读:
    linux redis安装 5.0.2
    Linux nginx安装步骤 centos7
    fastjson JSONObject.toJSONString 出现 $ref: "$."的解决办法(重复引用)
    docker redis安装及配置(外网访问 关闭安全限制 设置密码)
    JDK dump
    mysql8 修改root密码
    docker系列详解<二>之常用命令
    获取地理位置
    js调用摄像头
    点击时扩散效果
  • 原文地址:https://www.cnblogs.com/nayitian/p/14899429.html
Copyright © 2011-2022 走看看