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

  • 相关阅读:
    沙盒配置好的测试
    云端存储的实现:云存储1
    演职人员名单MobileMenuList
    关于GitHub的朋友的NE Game
    到了冲刺阶段
    云存储的配置3
    刚才花了1$赞助了那位伙计
    我知道这对自己是个积累的过程,很好,我成长的很快
    煎熬过后终于有一刻释怀
    空白不曾停止。。。
  • 原文地址:https://www.cnblogs.com/nayitian/p/14899429.html
Copyright © 2011-2022 走看看