代码之家  ›  专栏  ›  技术社区  ›  Maksim Dmitriev

Java中同步语句的静态锁对象

  •  1
  • Maksim Dmitriev  · 技术社区  · 12 年前

    请不要陷入这样的陷阱,即你可以锁定A类的任意实例,这将以某种方式锁定A类的另一个实例。这是一个经典的初学者错误。

    我犯了好几次错误才明白。但静态锁对象工作正常。

    我的线程

    package com.replanet;
    
    public class MyThread extends Thread {
    
        private int x, y;
        private static Object lock3 = new Object();
    
        public MyThread(int x, int y) {
            this.x = x;
            this.y = y;
        }
    
        @Override
        public void run() {
            super.run();
            try {
                test_Method();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
    
        }
    
        private void test_Method() throws InterruptedException {
            synchronized (lock3) {
                System.out.println("test_Method " + Thread.currentThread().getName());
                for (int i = 0; i < Integer.MAX_VALUE; i++) {
                    if (i == Integer.MAX_VALUE / 2) {
                        Thread.sleep(2000);
                        System.out
                                .println("Leaving test_Method on " + Thread.currentThread().getName());
                        return;
                    }
                }
            }
        }
    
    }
    

    用法

    package com.replanet;
    
    public class Main {
    
        public static void main(String[] args) {
    
            MyThread myThread1 = new MyThread(1, 2);
            MyThread myThread2 = new MyThread(1, 2);
            myThread1.start();
            myThread2.start();
        }
    }
    

    输出

    test_Method Thread-0
    Leaving test_Method on Thread-0
    test_Method Thread-1
    Leaving test_Method on Thread-1
    

    带有非静态锁定对象的输出(不适合我)

    test_Method Thread-0
    test_Method Thread-1
    Leaving test_Method on Thread-1
    Leaving test_Method on Thread-0
    

    使用它是个好主意吗 static 锁定对象?

    3 回复  |  直到 12 年前
        1
  •  3
  •   Boris the Spider    12 年前

    你可以锁定 Class 本身-这更有意义,也更容易阅读:

    private void test_Method() throws InterruptedException {
            synchronized (MyThread.class) {
                System.out.println("test_Method " + Thread.currentThread().getName());
                for (int i = 0; i < Integer.MAX_VALUE; i++) {
                    if (i == Integer.MAX_VALUE / 2) {
                        Thread.sleep(2000);
                        System.out
                                .println("Leaving test_Method in " + Thread.currentThread().getName());
                        return;
                    }
                }
            }
        }
    

    或者,如果不需要将该方法作为实例方法:

    private static synchronized void test_Method() throws InterruptedException {
                System.out.println("test_Method " + Thread.currentThread().getName());
                for (int i = 0; i < Integer.MAX_VALUE; i++) {
                    if (i == Integer.MAX_VALUE / 2) {
                        Thread.sleep(2000);
                        System.out
                                .println("Leaving test_Method in " +  Thread.currentThread().getName());
                        return;
                    }
                }
        }
    

    你可能还想了解一下新的(ish) Lock

        2
  •  1
  •   Joop Eggen    12 年前

    而不是 静止的 最好让MyThread共享一个锁对象。更加面向对象。

        3
  •  0
  •   Marko Topolnik    12 年前

    它是静态成员还是实例成员取决于您希望它具有的作用域,但具体是什么 一个好的做法是 私有的 要锁定的对象。这是锁定(显然是公共的)类对象的主要优势。