简体   繁体   English

关于相同/不同对象上的Java线程的困惑

[英]Confusion Regarding java threads on same/different objects

public class Computation extends Thread {

    private int num;
    private boolean isComplete;

    public Computation(int nu) {
        num = nu;
    }

    public void run() {
        System.out.println("Thread Called is: " + Thread.currentThread().getName());
    }

    public static void main(String... args) {
        Computation [] c = new Computation[4];
        for (int i = 0; i < 3; i++) {
            c[i] = new Computation(i);
            c[i].start();
        }
    }
}

My Question is in main function we are creating every time a new Computation object on which the thread is being started then why we need to snchrnoized the run method? 我的问题是,在每次启动要在其上启动线程的新Computation对象的主要功能中,为什么我们需要对run方法进行分类? As we know for every different class object 'this' reference is different so we don't need to synchronize. 众所周知,对于每个不同的类对象,“此”引用都是不同的,因此我们不需要同步。

Also in another Example: 同样在另一个示例中:

public class DiffObjSynchronized implements Runnable {

    @Override
    public void run() {
        move(Thread.currentThread().getId());           
    }

    public synchronized void move(long id) {
        System.out.print(id + " ");
        System.out.print(id + " ");
    }

    public static void main(String []args) {
        DiffObjSynchronized a = new DiffObjSynchronized();
        /**** output ****/
        // 8    9   8   9
        new Thread(a).start();
        new Thread(new DiffObjSynchronized()).start();
    }
}

Here is second example just like first we create a Thread on 2 different instances of class. 这是第二个示例,就像第一个示例一样,我们在2个不同的类实例上创建一个线程。 Here we synchronize the move() method but by definition: "two different objects can enter the synchronized method at the same time" 在这里,我们同步了move()方法,但是根据定义:“两个不同的对象可以同时进入同步的方法”

Please share your feedback? 请分享您的反馈?

Your threads are operating on different objects since you create a new instance for each thread. 由于您为每个线程创建了新实例,因此线程在不同的对象上运行。 The intrinsic lock used by synchronized belongs to the instance. 同步使用的内部锁属于实例。 So the synchronized methods entered by your threads are guarded by different locks. 因此,线程输入的同步方法由不同的锁保护。

If I understand you correctly, your question is: "Why is the move method synchronized?" 如果我对您的理解正确,那么您的问题是:“为什么要同步move方法?”

The answer is: it shouldn't be, for two reasons: 答案是:不应这样做,有两个原因:

  1. It doesn't access any fields, so there is nothing that could be corrupted by having many threads inside that method at once. 它不访问任何字段,因此不会因为一次在该方法中包含多个线程而损坏任何内容。

  2. Each thread gets a different instance of the object, and thus a different lock. 每个线程都获得对象的不同实例,从而获得不同的锁。 So the synchronized modifier makes no difference. 因此,同步修饰符没有区别。 Each thread can still enter its own instance's move method because they have separate locks. 每个线程仍然可以输入其自己实例的move方法,因为它们具有单独的锁。

You only need to synchronize when you have some data which is being shared between threads, and at least one thread is modifying that data. 仅当线程之间共享某些数据并且至少有一个线程正在修改该数据时,才需要同步。

You need to understand how synchronization works. 您需要了解同步的工作原理。 Threads take a 'lock' on the object on which you are synchronizing when they enter the synchronized block. 当线程进入同步块时,线程会在要同步的对象上“锁定”。 If you have a synchronized method then in that case the object becomes the 'this' instance. 如果您具有同步方法,则在这种情况下,该对象将成为“ this”实例。 Now, no 2 threads can take a lock on the same object at the same time. 现在,没有2个线程可以同时对同一个对象进行锁定。 object locks are mutex based in philosophy so only once thread can hold the mutex at a time. 对象锁在原理上是基于互斥锁的,因此线程一次只能容纳一个互斥锁。 When the thread holding the lock exits the synchronized method or the block, it releases the mutex and thus the object lock becomes available to other threads to request lock on. 当持有锁的线程退出同步方法或块时,它将释放互斥锁,因此对象锁可用于其他线程以请求锁。

This link explains the concepts excellently. 链接很好地解释了这些概念。 It has pictures about disassembled byte code which shows how threads take and leave locks and why 2 threads on 2 different object dont block each other. 它包含有关反汇编字节码的图片,这些图片显示了线程如何获取和保留锁以及为什么两个不同对象上的2个线程不会互相阻塞。

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

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