繁体   English   中英

调用同步方法时线程调用非同步实例方法

[英]Thread calling non-synchronized instance method when a synchronized method is called

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  

我想找到一种方法来防止在我调用syncedMethod1时method1()运行。 除非我没有记错,否则所有方法都将被调用,并且Java在运行时以及运行时进行编译,无论是否同步。

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

我想找到一种方法来防止在我调用syncedMethod1时method1()运行

最简单的方法是使method1()synchronized 这意味着这两种方法都将导致它们正在调用的Common实例上的锁定。 只有一个线程将能够调用synchronizedMethod1()method1()

除非我没有记错,否则所有方法都将被调用,并且Java在运行时以及运行时进行编译,无论是否同步。

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

我应该改用Lock对象吗?

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

如果你想method1synchronizedMethod1是相互排斥的,那么你需要用相同的锁来保护他们。 无论是使用Lock还是简单地在同一Object实例上调用synchronize ,结果都大致相同。

在关闭的机会,你要多线程被允许执行method1 ,但不是当synchronizedMethod1被调用时,你需要一个ReadWriteLock来实现这一目标。

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();
        }
    }
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM