关于java的多线程的成员变量是否线程安全的疑问?
大家讲道理
大家讲道理 2017-04-18 10:49:12
0
14
1437

对于下面的程序:

public class MyThread extends Thread{
    private Object obj;
    ......
}

请问,这个MyThread里面的成员变量,是不是线程安全的?

因为,MyThread继承了Thread,其使用方式为:new MyThread().start();
所以,这就意味着,每次都是new了新对象,那么,他里面的各个成员变量就是这个对象自己拥有的,所以,是安全的。
我这样理解有问题吗?

大家讲道理
大家讲道理

光阴似箭催人老,日月如移越少年。

répondre à tous(14)
PHPzhong

Si la sécurité des threads est liée au fait qu'elle soit utilisée dans plusieurs threads

Bien que vous ayez défini private, il existe de nombreuses façons d'y accéder indirectement dans d'autres threads, il est donc possible de l'utiliser dans plusieurs threads, mais aucun traitement de synchronisation n'est ajouté au code, ce n'est donc pas sûr.

Supplément

Il n'y a aucune différence entre utiliser Thread et Runnable :

public class Test {
    public static void main(String[] args) throws Exception {
        MyThread mt = new MyThread();
        new Thread(mt).start();
        new Thread(mt).start();
        new Thread(mt).start();

        // MyRunable mr = new MyRunable();
        // new Thread(mr).start();
        // new Thread(mr).start();
        // new Thread(mr).start();
    }
}

class MyThread extends Thread {
    private int ticket = 10;

    public void run() {
        for (int i = 0; i < 20; i++) {
            if (this.ticket > 0) {
                System.out.println("thread: " + this.ticket--);
            }
        }
    }
}

class MyRunable implements Runnable {
    private int ticket = 10;

    public void run() {
        for (int i = 0; i < 20; i++) {
            if (this.ticket > 0) {
                System.out.println("runable: " + this.ticket--);
            }
        }
    }
}

Un exemple courant sans cas (il faut l'exécuter plusieurs fois pour le trouver)

thread: 10
thread: 9
thread: 7
thread: 10
thread: 6
thread: 8
thread: 3
thread: 4
thread: 5
thread: 1
thread: 2
左手右手慢动作

Chaque fois qu'un nouvel objet est créé, la carte qu'il contient appartient à l'objet lui-même, elle est donc sûre.

Cette phrase est correcte, sauf si vous déclarez un membre public (variable) dans le thread principal qui appelle le sous-thread et exploitez la variable publique à l'intérieur du sous-thread, ou si vous transmettez la variable publique par référence dans Cela conduira à l'émergence de problèmes d'insécurité des threads. Quant à savoir si le type de carte lui-même est thread-safe, j'ai également oublié (je me souviens que la carte est une interface. Qu'elle soit thread-safe ou non en dépend. Pour son implémentation spécifique) , vous pouvez le rechercher sur Baidu. . .

Si l'implémentation de map elle-même est thread-safe, alors peu importe la façon dont vous opérez à l'intérieur de plusieurs threads, tout ira bien. (Même s'il est déclaré dans le thread principal et passé par référence au sous-thread)

Pour des connaissances scientifiques spécifiques sur la sécurité des fils, vous pouvez lire les articles que j'ai écrits avant https://zhuanlan.zhihu.com/p/...

PHPzhong

Comment dire, c'est comme :
Vous avez mis l'argent dans votre valise et vous avez marché seul dans la rue.
Vous pensez que c’est sûr, bien sûr.
Mais une fois volé, ce n'est plus sûr. . .

La sécurité des threads signifie que différents threads accèdent aux mêmes données. S'il n'y a qu'un seul thread, il n'y a pas de sécurité des threads. Ou vous pouvez aussi le comprendre comme "sûr", après tout, aucun autre objet ne peut y accéder, mais il n'est pas "thread safe"

Répondez à la question :

Cet objet cartographique est-il dangereux pour les threads ?

Oui, thread-unsafe.
Car bien que chaque objet Thread ait ici un objet Map unique et indépendant, il n'a pas de "capacités de sécurité des threads".
Eh bien, c'est ce que je comprends, cela semble un peu verbeux. . . ==

小葫芦

Merci pour l'invitation !
est lorsque restreint l'utilisation de new MyThread().start() à 线程安全.

迷茫

Bien que vous la déclariez privée, la variable peut toujours être lue dans un autre thread. Elle n'est pas sécurisée sans verrou de synchronisation.

题主想的这种线程安全的变量应该是在run方法里面声明的,这样的话对象就存在于线程工作内存里独享。
迷茫

La lecture est très bien, l'écriture entraînera des problèmes de sécurité des threads. . .

1. Utilisez des méthodes de classe thread-safe

2. Utilisez ThreadLocal

PHPzhong

Considérez MyThread simplement comme une classe (ne pensez pas que ce soit une classe de fil), pensez à obj simplement comme un membre de cette classe. Cela devient alors plus facile à comprendre.

伊谢尔伦

Dans le cas du multi-threading

public class MyThread extends Thread{
    private Object obj;
    public void run(){
        if(obj==null){//A位置,这个地方是关键
            obj = new  Object();
            system.out.println("null");
        }
    }
}

MyThread thread = new MyThread();
//假设我的系统CPU是4核,那么实际上系统可以同时并行跑4个线程,这个时候我是同一个对象,
//假设我第一个跑到A的位置,第二个也刚好跑到这个位置,
//那当我第一个跑完obj是==null走到下一步的时候,obj已经重新new一个对象,
//这个时候obj!=null,这可能导致的结果就是有部分无法走进A代码块里面去,
//实际上在程序设计上应该需要让他走到A代码里面去的,这样就导致了线程安全的问题。
thread.start();
thread.start();
thread.start();
thread.start();
PHPzhong

Cela dépend principalement du fait que vous avez accédé à une certaine ressource publique. Cette question n'implique pas l'accès à une certaine ressource publique, on ne peut donc pas dire qu'elle est sûre ou dangereuse.

洪涛

Cela dépend principalement si vous avez opéré sur cette variable, et en supposant que vous créez un nouvel objet à chaque fois, il est thread-safe.

Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal
À propos de nous Clause de non-responsabilité Sitemap
Site Web PHP chinois:Formation PHP en ligne sur le bien-être public,Aidez les apprenants PHP à grandir rapidement!