是否可以从不同的类线程更改实例变量的值获取锁

时间:2016-07-21 11:43:50

标签: java multithreading synchronization

是否可以在获取锁定后从不同的类线程更改实例变量的值。

我有一个ThreadTest类,它有String测试实例变量。 在Run方法中,我对String测试实例变量进行了锁定。

如果JVM已经对实例变量进行了锁定,那么为什么我能够从主线程更改它的值。

ThreadTest.class

package com;

公共类ThreadTest实现Runnable {

String test;
int i=100;

public ThreadTest(String test) {
    super();
    this.test = test;
}


@Override
public void run() {
    // TODO Auto-generated method stub


//  Thread.currentThread().dumpStack();
    while(i>0)
    {   
        synchronized(test){


        System.out.println("Thrad Test Run---  "+test+" - "+i+"- -- "+Thread.currentThread().getName());

            try {
                Thread.sleep(1000);

            } catch (Exception e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
        i--;
    }
}

}

的Test.class

package com;

公共课测试{

/**
 * @param args
 */
public static void main(String[] args) {
    // TODO Auto-generated method stub


    ThreadTest testThread=new ThreadTest("1");
    Thread thread=new Thread(testThread);
    thread.setName("First Thread");
    Thread thread1=new Thread(testThread);
    thread1.setName("Second Thread");

    thread.start();
    thread1.start();
    int i=100;  
    try {
        Thread.sleep(1000);
    } catch (InterruptedException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
    while(true)
    {
        //here im accessing the 'test' that is instance variable of ThreadTest.
        // and First Thread alredy acquired a lock on 'test'.
        //so according to the JAVA threading testThread.test=10 is not valid.
        //how multiple threads are able to change the value of testThread.test
        testThread.test="10";
        //System.out.println("main thread...");
    }



}

}

2 个答案:

答案 0 :(得分:0)

似乎对同步语句的作用存在疑惑。

  1. 同步不会锁定实例变量,它会锁定'一个东西。 (实际上,锁定'不是这里使用的词。它获取对象' monitor'。)当使用synchronized语句时(如上所述),评估提供的表达式以确定要获取哪个对象的监视器。例如,这里是有效的,虽然可能是荒谬的同步语句:

    app.controller('One', ['$scope', '$rootScope'
        function($scope) {
            $rootScope.$on("CallParentMethod", function(){
               $scope.parentmethod();
            });
    
            $scope.parentmethod = function() {
                // task
            }
        }
    ]);
    app.controller('two', ['$scope', '$rootScope'
        function($scope) {
            $scope.childmethod = function() {
                $rootScope.$emit("CallParentMethod", {});
            }
        }
    ]);
    

    第一个获取String对象上的监视器,表示字符串文字" 1"。第二个是在一个全新的对象上获取监视器(从不用于管理并发)。

  2. synchronized 用于标记程序中的关键部分。关键部分是不能同时执行的代码块。 See Critical Section on Wikipedia

    关于上面的代码, synchronized 不会阻止实例(或类)变量的读取或写入。

  3. 以下内容可能会有所帮助:Synchronization from the Java Tutorial

答案 1 :(得分:0)

  

获得锁定后是否可能......

如果线程A获得锁定,则不会限制线程A以任何方式执行任何操作的能力。

如果线程A获得了一个锁,它限制了线程B完成一件事的能力:它阻止线程B获得相同的锁,直到线程A释放它。它不会阻止线程B执行任何其他操作。特别是,它不会阻止线程B访问或修改被锁定的对象"。

  

是否可以更改实例变量的值...

是的,如果变量不是$totalItems: 12; $itemWidthIncrement: 3px; $itemMarginIncrement: 1px; @for $i from 1 through $totalItems { .item-:nth-child(#{$i}) { float: if($i % 2 == 0, left, right); width:/*get previous item here*/ + $itemWidthIncrement; } }

  

......来自不同的班级

A类中的方法是否可以直接引用B类中声明的变量取决于访问级别finalprivate,{{1}在变量声明中指定的,或默认)。 https://docs.oracle.com/javase/tutorial/java/javaOO/accesscontrol.html

protected块的使用和线程的使用不会以任何方式改变访问级别的含义。

当然,A类中的方法也可以通过调用B类的某个方法间接影响B类中的public变量。

  

...来自不同的......线程

如果A类中的方法可以直接或间接地影响在B类中声明的变量,那么执行该方法的线程无关紧要。所有线程都看到相同的堆。