线程内在锁

时间:2010-07-29 10:18:17

标签: java multithreading

当我们谈论内在锁时,我们引用我们要求锁的对象 或者用于同步方法?

锁是在对象上还是在同步方法上?

我很困惑!

7 个答案:

答案 0 :(得分:16)

内部锁在对象上:

class A
{
   public synchronized void method1(){...}
   public synchronized void method2(){...}
}

如果线程A在method1中,则threadB无法进入method2。

答案 1 :(得分:10)

在Java中,每次使用synchronized关键字

都会隐含内在锁定

synchronized关键字的每次使用都与两种类型的内部锁定之一相关联:

"实例锁定",附加到单个对象

a"静态锁定",附加到类

如果一个方法被声明为synchronized,那么它将在调用时获取实例锁或静态锁,具体取决于它是实例方法还是静态方法。

这两种类型的锁具有相似的行为,但完全相互独立。

获取实例锁只会阻止其他线程调用同步实例方法;它不会阻止其他线程调用非同步方法,也不会阻止它们调用静态同步方法。

类似地,获取静态锁仅阻止其他线程调用静态同步方法;它不会阻止其他线程调用非同步方法,也不会阻止它们调用同步实例方法。

在方法标题之外,synchronized(this)获取实例锁。

静态锁可以通过两种方式在方法头之外获取:

synchronized(Blah.class),使用类文字

synchronized(this.getClass()),如果对象可用

答案 2 :(得分:4)

同步方法将方法锁定在对象

synchronized void methodA () {
    ....    
}

某种程度上相当于

void methodA () {
    synchronized (this) {
        ....
    }
}

答案 3 :(得分:1)

锁是Object的一部分。每个对象都有一个,它可以通过两种方式锁定:

  1. 在Class的实例方法上使用synchronized修饰符来锁定关联对象
  2. 使用synchronized(object) {}
  3. 同样,您可以锁定对象的类而不是对象本身(单独提及以使用synchronized方法理解static修饰符):

    1. 在Class的静态方法上使用synchronized修饰符来锁定类
    2. 使用synchronized(clazz) {}块,其中clazz是对象的类

答案 4 :(得分:0)

锁定在对象上。在Java中,每个对象都是monitor

答案 5 :(得分:0)

library(biomaRt)
marts <- listMarts()
ensembl <- useMart("ensembl")
datasets <- listDatasets(ensembl)
ensembl=useDataset("hsapiens_gene_ensembl",mart=ensembl)
attributes <- listAttributes(ensembl)
my_ids <- read.csv("/home/firat/Desktop/ahmet_deseq2_results.csv")
results_end_1 <- getBM(attributes = c("ensembl_gene_id","external_gene_name"), values = my_ids, mart = ensembl )
View(results_end_1)
merged_with_my_ids <- merge(my_ids,results_end_1,by.x = "X",by.y = ,"ensembl_gene_id")
View(merged_with_my_ids)

在上面的例子中,我有2个线程试图增加count的值。为了防止线程交错,我试图通过使用 synchronized 关键字来获取内部锁定。

决定性, 在此示例中,锁定 方法块 countFunc ,其中包含 同步 关键字锁定 计数变量。 希望这有帮助

答案 6 :(得分:0)

锁在对象上。

查看intrinsic locks

上的java教程页面
  

每个对象都有一个与之关联的内在锁。按照惯例,需要对对象字段进行独占和一致访问的线程必须在访问对象之前获取对象的内部锁,然后在完成它们时释放内部锁。据说一个线程在获得锁定和释放锁定之间拥有内在锁定。

只要线程拥有内部锁,就没有其他线程可以获得相同的锁。另一个线程在尝试获取锁时会阻塞。

使用内部锁的两种方法:

  1. 同步方法:

    当线程调用synchronized方法时,它会自动获取该方法对象的 内在锁 ,并在方法返回时释放它。

    e.g。

    public synchronized void incrementCounter(){
        ++counter;
    }
    
  2. 同步语句

    synchronized方法不同,synchronized语句必须指定提供内部锁的对象

    public int getCounter(){
        synchronized(this){
            return counter;
        }
    }
    

    完整示例:

    public class SynchronizedDemo{
    private int counter = 0;
    
    public SynchronizedDemo(){
    
    }
    public synchronized void incrementCounter(){
        ++counter;
    }
    public int getCounter(){
        synchronized(this){
            return counter;
        }
    }
    public static void main(String[] args){
        SynchronizedDemo object = new SynchronizedDemo();
        for ( int i=0; i < 5; i++){
            Thread t = new Thread(new SimpleRunnable(object));
            t.start();
        }           
    }
    }
    class SimpleRunnable implements Runnable{
    private SynchronizedDemo object;
    
    public SimpleRunnable(SynchronizedDemo obj){
        this.object = obj;
    }
    public void run(){
        object.incrementCounter();
        System.out.println("Counter:"+object.getCounter());
    }
    }
    
  3. 注意: 此示例仅用于展示使用内部锁的不同方法。对于这种用例,使用AtomicInteger作为计数器变量是正确的方法。