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%\bin\java "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