JAVA线程安全关于synchronized关键字的用法,今天才知道原来我一直错了。以为用了synchronized关键字包住了代码就可以线程同步安全了。
测试了下。发现是完全的错了。synchronized必须正确的使用才是真正的线程安全。。。虽然知道这种写法,一直以为却由于懒而用了错误的方法。
看来基础还没有打好。仍需复习加强!工作中犯这种错误是不可原谅的,要知道使用synchronized关键字的地方都是数据敏感的!汗一把。。。
先贴代码:
[java]view plaincopyprint?
- package com;
- publicclass ThreadTest {
- publicstaticvoid main(String[] args) {
- MyThread m1 = new MyThread(1);
- MyThread m2 = new MyThread(2);
- m1.start();
- m2.start();
- }
- }
- finalclass MyThread extends Thread {
- privateint val;
-
- public MyThread(int v) {
- val = v;
- }
- //这种做法其实是非线程安全的
- publicsynchronizedvoid print1(int v) {
- for (int i = 0; i < 100; i++) {
- System.out.print(v);
- }
- }
-
- publicvoid print2(int v) {
- //线程安全
- synchronized (MyThread.class) {
- for (int i = 0; i < 100; i++) {
- System.out.print(v);
- }
- }
- }
-
- publicvoid run() {
- print1(val);
- // print2(val);
- }
- }
package com; public class ThreadTest { public static void main(String[] args) { MyThread m1 = new MyThread(1); MyThread m2 = new MyThread(2); m1.start(); m2.start(); } } final class MyThread extends Thread { private int val; public MyThread(int v) { val = v; } //这种做法其实是非线程安全的 public synchronized void print1(int v) { for (int i = 0; i < 100; i++) { System.out.print(v); } } public void print2(int v) { //线程安全 synchronized (MyThread.class) { for (int i = 0; i < 100; i++) { System.out.print(v); } } } public void run() { print1(val); // print2(val); } }
还是为了偷懒,汗一把。。。程序员总是懒的吧。能少写就少写。我把MyThread写成了一个匿名的最终的内部类,方便调用。它用了最直接的继承Thread来实现一个线程类,定义需要运行的run()方法。
首先注释了print2()方法,看看print1()的结果如何。print1()是一个使用了synchronized关键字定义的方法,我一直以为这样也可以实现线程安全。殊不知,我错了。
我们来直接运行main()方法。控制台打印结果如下:
1212111121212121212121212121212121212121222222212121212。。。
是一连串1和2交叉打印的结果。而我main方法中是先运行m1再运行m2的,显示没有做到线程同步!