0
public class Common {      
    public synchronized void synchronizedMethod1() {
        System.out.println("synchronizedMethod1 called");
        try {
            Thread.sleep(1000);
            } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("synchronizedMethod1 done");
    }
    public void method1() {
        System.out.println("Method 1 called");
        try {
            Thread.sleep(1000);
            } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("Method 1 done");
    }
}



public class MyThread extends Thread {
    private int id = 0;
    private Common common;

    public MyThread(String name, int no, Common object) {
        super(name);
        common = object;
        id = no;
    }

    public void run() {
        System.out.println("Running Thread" + this.getName());
        try {
            if (id == 0) {
                common.synchronizedMethod1();
                } else {
                common.method1();
            }
            } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public static void main(String[] args) {
        Common c = new Common();
        MyThread t1 = new MyThread("MyThread-1", 0, c);
        MyThread t2 = new MyThread("MyThread-2", 1, c);
        t1.start();
        t2.start();
    }
}

输出:

Running ThreadMyThread-1  
synchronizedMethod1 called  
Running ThreadMyThread-2  
Method 1 called  
synchronizedMethod1 done  
Method 1 done  

当我调用 synchronizedMethod1 时,我想找到一种方法来阻止 method1() 运行。除非我弄错了,所有方法都被调用,Java 在运行时和运行前编译它们,不管它是否同步。

我应该改用 Lock 对象和/或不也使 method1() 成为同步方法吗?

4

2 回答 2

1

当我调用 synchronizedMethod1 时,我想找到一种方法来阻止 method1() 运行

最简单的方法是 make method1()also be synchronized。这将意味着这两种方法都将导致对Common它们正在调用的实例的锁定。只有一个线程可以调用synchronizedMethod1()或调用method1().

除非我弄错了,所有方法都被调用,Java 在运行时和运行前编译它们,不管它是否同步。

我不明白这个问题。您真的不必担心 JVM 的编译或优化阶段。

我应该改用 Lock 对象吗?

通常制作方法synchronized被认为不如使用private final锁对象好。锁定对象只是让你的锁更细粒度。例如,使用方法锁定,日志消息和其他不需要保护的语句也会如此synchronized。但是如果目标是锁定整个方法,那么同步方法就可以了。

于 2012-07-18T20:10:14.997 回答
0

如果你想要method1并且synchronizedMethod1是互斥的,那么你需要用相同的锁来保护它们。无论是使用 aLock还是简单地调用synchronize同一个 Object 实例,结果都大致相同。

如果您希望允许执行多个线程method1但不希望在synchronizedMethod1被调用时执行,则需要 aReadWriteLock来完成此操作。

public class Common {     
    ReadWriteLock rwLock = new ReentrantReadWriteLock();

    public void synchronizedMethod1() {
        rwLock.writeLock().lock();
        try {
            System.out.println("synchronizedMethod1 called");
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("synchronizedMethod1 done");
        } finally {
            rwLock.writeLock().unlock();
        }
    }
    public void method1() {
        rwLock.readLock().lock();
        try {
            System.out.println("Method 1 called");
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("Method 1 done");
        } finally {
            rwLock.readLock().unlock();
        }
    }
}
于 2012-07-18T20:25:09.800 回答