Java监视器包括实例变量吗?

17 浏览
0 Comments

Java监视器包括实例变量吗?

在Java中,监视器对实例变量的访问没有限制,只限制在声明为同步或在同步语句中的方法。我创建了两个线程,线程y调用声明为同步的sync()方法,而线程r调用未声明为同步的unsync()方法。它们都在共享对象s上调用方法。

当线程y仍然持有对象s的监视器或锁时,线程r能够修改对象s的实例变量。

在Java中,监视器对实例变量的访问没有限制,只限制在声明为同步或在同步语句中的方法吗?

程序的输出如下:

Okay, I am in sync() method. I will be waiting for 10 seconds. Current Time = 1358801766310

Alright, I am in unsync() method. The current time is 1358801768343. The time of exit from unsync() method is 1358801768343

Okay, I have waited for 10 seconds. Current time is 1358801776310. Now I will exit from sync() method, a = 11

0
0 Comments

在Java中,将方法声明为synchronized具有两个效果:

首先,同一个对象上的两个同步方法的调用不可能交错执行。当一个线程执行一个对象的同步方法时,所有调用该对象的同步方法的其他线程都会被阻塞,直到第一个线程完成对象的操作。

其次,当一个同步方法退出时,它会自动与后续对同一对象的同步方法的调用建立happens-before关系。这保证了对对象状态的更改对所有线程都是可见的。

然而,这种同步方法的机制并不适用于实例变量。实例变量是每个对象独有的,每个对象都有自己的一份实例变量。因此,不同线程对于同一个对象的实例变量的访问并不会相互阻塞或建立happens-before关系。

这就导致了一个问题:Java监视器是否包括实例变量?

解决这个问题的方法是使用synchronized关键字来修饰实例变量的访问方法。这样一来,当一个线程正在执行该方法时,其他线程将被阻塞,直到第一个线程完成对实例变量的操作。

下面是一个示例代码,展示了如何使用synchronized关键字来同步实例变量的访问:

public class MyClass {
    private int myVariable;
    public synchronized int getMyVariable() {
        return myVariable;
    }
    public synchronized void setMyVariable(int value) {
        myVariable = value;
    }
}

在上面的代码中,getMyVariable()和setMyVariable()方法都被声明为synchronized,这样就确保了对myVariable实例变量的访问是同步的。

通过使用synchronized关键字来同步实例变量的访问,可以解决Java监视器是否包括实例变量的问题。这样一来,多个线程对于同一个对象的实例变量的访问将是同步的,避免了并发访问导致的数据不一致性和竞态条件的问题。

0
0 Comments

在Java中,监视器(monitor)并不限制对实例变量的访问,而只限制对声明为同步的方法或在同步语句中的代码的访问。

因此,如果想要限制对变量的访问,就需要确保所有的访问都是在持有锁(任何锁,只要对于每次访问都是相同的)的情况下进行的。

解决方法就是在对变量进行访问时,使用同一个锁对象进行同步,以确保在任何时候只有一个线程可以访问变量。这可以通过在访问变量的代码块或方法上使用synchronized关键字来实现。

例如,下面的代码展示了如何使用同步块来限制对变量的访问:

public class Example {
    private Object lock = new Object();
    private int variable = 0;
    
    public void incrementVariable() {
        synchronized (lock) {
            variable++;
        }
    }
    
    public void decrementVariable() {
        synchronized (lock) {
            variable--;
        }
    }
    
    public int getVariable() {
        synchronized (lock) {
            return variable;
        }
    }
}

在上述示例中,变量variable的访问被限制在使用相同的锁对象lock进行同步的代码块中。这样,无论多少个线程同时访问variable,都只有一个线程可以进行访问,从而保证了对variable的安全访问。

总之,Java中的监视器并不直接限制对实例变量的访问,但可以通过使用同步块或方法来实现对变量的限制访问。

0
0 Comments

原因:Java中的监视器包括实例变量。这是因为当一个线程持有一个对象的监视器时,其他线程不能执行该对象上的另一个代码块或同步。如果一个方法没有同步,任何线程都可以在任何时候调用它,无论另一个线程是否持有监视器。

解决方法:如果存在至少一个线程修改共享状态的可能性,那么必须对每次访问共享状态(即使只是只读访问)进行同步。

0