如果线程不请求锁本身,则线程可以更改java锁对象数据吗?

奥利弗·斯科特(Oliver Scott)

Oracle的本征锁和同步教程说:

Intrinsic [Monitor]锁在同步的两个方面都起作用:强制对对象状态的独占访问

我假设如果一个线程正在执行“同步”方法,则一个对象中的任何值都不能同时由两个线程操纵。

因此,当以下代码具有以下输出时,我感到很惊讶(尽管出于我想要做的目的而松了一口气)。我不太确定会发生什么,但是我发现有错误或可能会发生某些情况。

据我了解,如果另一个线程正在请求该对象的监视状态,则“同步”仅用于限制对该对象的访问-但如果另一个线程正在更改一个值,则不是。它是否正确?

public class HelloWorld implements Runnable{
    Thread t1;
    Thread t2;
    int val1 = 0;
    int val2 = 0;

    public static void main(String[] args) {
        HelloWorld h1 = new HelloWorld();
        h1.t1 = new Thread(h1);
        h1.t2 = new Thread(h1);
        h1.t1.start();
        h1.t2.start();
    }

    @Override
    public void run() {
        System.out.println("STARTED");
        System.gc();
        Thread currentThread = Thread.currentThread();

        if (currentThread == this.t1) { 
            this.locker(); //This is a synchronized method, incrementing val1
        }
        if (currentThread == this.t2) {
            this.adder();  //This is a non-synchronized method, incrementing val2
        }
    }

    private synchronized void locker() {
        for(int i = 0; i < 3; i++){
            val1++;
            System.out.println("LOCKER: " + this.val1);
        }
    }

    private void adder() {
        while(this.val2 < 3) {
            this.val2++;
            System.out.println("ADDER: " + this.val2);
        }
        synchronized(this) {  
        //Synchronize for final output
            System.out.println("FINAL");
            System.out.println(val1);
            System.out.println(val2);     
        }
    }

}

STARTED
STARTED
ADDER: 1
LOCKER: 1
LOCKER: 2
ADDER: 2
LOCKER: 3
ADDER: 3
FINAL
3
3
怀疑论者

措辞“强制对对象状态的专有访问”可能会引起误解。同步代码可用于实现对对象状态的互斥访问,但是(a)并不强制这样做,并且(b)受保护状态不一定是被锁定对象的状态。在该教程后面的示例中对此进行了演示,其中两个对象lock1lock2用于保护字段,c1c2这两个字段都不属于其自身状态。

什么synchronized强制执行是独占访问代码-这是一个中的任何代码synchronized在同一个显示器上块只能由拥有该监视器线程跑出。这可以用于确保对状态的独占访问-但前提是您正确编写了代码(即,将对状态的所有访问都放在synchronized块中)。

没有什么可以阻止您编写从不受保护的代码访问字段的程序,在这种情况下,将不强制执行独占访问。

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

Java线程对象锁

Java线程可以在持有锁的同时获取锁吗?

Java 无法获取线程锁

几个线程可以在Java的同一监视器上保持锁吗?

多线程互斥锁可以使用几个互斥锁吗

互斥锁可以在不显式保护对象的情况下确保对象的线程可见性吗?

从没有锁的多个线程读取动态/更改数据?会导致崩溃吗?还是只是损坏的变量?

Java多线程多锁比单锁慢

后台线程中的核心数据锁

线程锁中的多线程

线程间传递锁

多线程和锁

线程同步-线程何时释放对象上的锁

带锁的Java多线程同步

Java多线程锁无法正常工作

停止线程并释放Java中的锁

如果线程在关键部分上调用Acquire(),如果其他线程调用Release(),则该锁将被释放吗?

对于预分配的数组,Ruby Array#[] =线程安全吗?可以将其设为无锁吗?

确保函数线程安全:特定于线程的数据与互斥锁

Java:如果始终在释放锁之前调用notify(),那么等待的线程将如何获取该相同的锁?

如果同一线程不断不断地获取锁,那么ReentrantLock公平吗?

如果不在多线程中使用锁,我是否可以以损坏的状态结束

如果不再更改对象,可以在线程之间安全地共享它吗?(Scala / Java)

如果只有一个线程使用互斥锁,线程之间的共享内存会被破坏吗?

使用互斥锁时,多个线程可以通过单个ØMQ套接字发送消息吗?

持有锁时可以在上下文中切换线程吗?

如果信号锁获取/ tryAcquire失败,如何使Java线程执行其他任务而不是阻塞?

如果线程正在等待互斥锁,是否捕获到信号?

是否可以在等待Java中特定锁的线程上调用notifyAll()?