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

  • 相关阅读:
    ASP.NET AJAX Sys未定义的解决方法
    幽默中的人生哲理
    我们总是试图抹去一些东西,比如记忆。然而,一切只是徒然。
    在webbrowser中操作js弹出的对话框 以及触发其它事件····
    Asp.Net :写入 、读取 、 删除、追加cookie数组?
    揭开ASP.NET中Cookie编程的奥秘
    多线程调度例子·····················
    winform编程——做过ini配置文件创建文件、添加配置项,修改配置项,删除配置项
    C# 比较二个时间差。Environment.TickCount
     WebBrowser控件捕捉DHTML事件
  • 原文地址:https://www.cnblogs.com/nayitian/p/14899429.html
Copyright © 2011-2022 走看看