cari

Rumah  >  Soal Jawab  >  teks badan

关于java的多线程的成员变量是否线程安全的疑问?

对于下面的程序:

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

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

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

大家讲道理大家讲道理2802 hari yang lalu1495

membalas semua(14)saya akan balas

  • PHPz

    PHPz2017-04-18 10:51:12

    Sama ada keselamatan benang berkaitan dengan sama ada ia digunakan dalam berbilang benang

    Walaupun anda mentakrifkan private, terdapat banyak cara untuk mengaksesnya secara tidak langsung dalam urutan lain, jadi adalah mungkin untuk menggunakannya dalam berbilang urutan, tetapi tiada pemprosesan penyegerakan ditambahkan pada kod itu.

    Tambahan

    Tiada perbezaan antara menggunakan Thread dan 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--);
                }
            }
        }
    }

    Contoh berjalan tanpa kes (anda perlu menjalankannya beberapa kali untuk mencarinya)

    thread: 10
    thread: 9
    thread: 7
    thread: 10
    thread: 6
    thread: 8
    thread: 3
    thread: 4
    thread: 5
    thread: 1
    thread: 2

    balas
    0
  • ringa_lee

    ringa_lee2017-04-18 10:51:12

    Setiap kali objek baharu dicipta, peta di dalamnya dimiliki oleh objek itu sendiri, jadi ia selamat.

    Ayat ini betul, melainkan anda mengisytiharkan ahli awam (pembolehubah) dalam utas utama yang memanggil sub-urutan dan mengendalikan pembolehubah awam di dalam sub-utas, atau anda menghantar pembolehubah awam melalui rujukan ke dalam Ini akan membawa kepada kemunculan masalah ketidakamanan benang Mengenai sama ada jenis peta itu sendiri selamat untuk benang, saya juga terlupa (saya ingat peta itu adalah antara muka. Sama ada ia selamat atau tidak bergantung padanya. Untuk pelaksanaan khusus beliau) , anda boleh mencarinya di Baidu. . .

    Jika pelaksanaan peta itu sendiri selamat untuk benang, maka tidak kira bagaimana anda beroperasi di dalam berbilang benang, ia akan baik-baik saja. (Walaupun ia diisytiharkan dalam utas utama dan diluluskan dengan merujuk kepada sub-utas)

    Untuk pengetahuan sains keselamatan benang khusus, anda boleh membaca artikel yang saya tulis sebelum ini https://zhuanlan.zhihu.com/p/...

    balas
    0
  • PHPz

    PHPz2017-04-18 10:51:12

    Cara meletakkannya, ia seperti:
    Anda memasukkan wang ke dalam beg pakaian anda dan berjalan di jalanan seorang diri.
    Anda fikir ia selamat, sudah tentu.
    Tetapi apabila ia dirompak, ia tidak selamat. . .

    Keselamatan utas bermaksud bahawa utas yang berbeza mengakses data yang sama Jika hanya terdapat satu utas, tiada keselamatan utas. Atau anda juga boleh memahaminya sebagai "selamat", selepas semua, tiada objek lain boleh mengaksesnya, tetapi ia bukan "selamat benang"

    Jawab soalan:

    Adakah benang objek peta ini tidak selamat?

    Ya, benang tidak selamat.
    Oleh kerana walaupun setiap objek Thread di sini mempunyai objek Peta yang unik dan bebas, ia tidak mempunyai "keupayaan keselamatan benang".
    Nah, ini pemahaman saya, nampaknya agak bertele-tele. . . ==

    balas
    0
  • 高洛峰

    高洛峰2017-04-18 10:51:12

    Terima kasih atas jemputan!
    ialah apabila mengehadkan penggunaan new MyThread().start() kepada 线程安全.

    balas
    0
  • 迷茫

    迷茫2017-04-18 10:51:12

    Walaupun anda mengisytiharkannya sebagai peribadi, pembolehubah masih boleh dibaca dalam urutan lain Ia tidak selamat tanpa kunci penyegerakan.

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

    balas
    0
  • 迷茫

    迷茫2017-04-18 10:51:12

    Membaca tidak mengapa, menulis akan menyebabkan masalah keselamatan benang. . .

    1. Gunakan kaedah kelas selamat benang

    2. Gunakan ThreadLocal

    balas
    0
  • PHPz

    PHPz2017-04-18 10:51:12

    Fikirkan MyThread hanya sebagai kelas (jangan fikir ia adalah kelas benang), fikirkan obj hanya sebagai ahli kelas ini. Kemudian ia menjadi lebih mudah untuk difahami.

    balas
    0
  • 伊谢尔伦

    伊谢尔伦2017-04-18 10:51:12

    Dalam kes pelbagai benang

    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();

    balas
    0
  • PHPz

    PHPz2017-04-18 10:51:12

    Ia bergantung terutamanya pada sama ada anda telah mengakses sumber awam tertentu Soalan ini tidak melibatkan akses kepada sumber awam tertentu, jadi ia tidak boleh dikatakan selamat atau tidak selamat.

    balas
    0
  • PHP中文网

    PHP中文网2017-04-18 10:51:12

    Ia bergantung terutamanya pada sama ada anda telah mengendalikan pembolehubah ini dan dengan mengandaikan bahawa anda mencipta objek baharu setiap kali, ia adalah selamat untuk benang.

    balas
    0
  • Batalbalas