search

Home  >  Q&A  >  body text

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

对于下面的程序:

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

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

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

大家讲道理大家讲道理2802 days ago1496

reply all(14)I'll reply

  • PHPz

    PHPz2017-04-18 10:51:12

    Whether thread safety is related to whether it is used in multiple threads

    Although what you defined is private, there are many ways to access it indirectly in other threads, so it is possible to use it in multiple threads, but there is no synchronization processing added to the code, so it is not safe.

    Supplement

    There is no difference between using Thread and 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--);
                }
            }
        }
    }

    A running example without a case (you have to run it a few times to find it)

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

    reply
    0
  • ringa_lee

    ringa_lee2017-04-18 10:51:12

    Every time a new object is created, the map inside it is owned by the object itself, so it is safe.

    This sentence is correct, unless you declare a public member (variable) in the main thread that calls the sub-thread and operate this public variable inside the sub-thread, or you pass this public variable into the sub-thread by reference Inside the thread and operating it inside the sub-thread, this will lead to thread insecurity problems. As for whether the map type itself is thread-safe, I have forgotten it (I remember that map is an interface, whether it is thread-safe or not depends on it. For specific implementation), you can search it on Baidu. . .

    If the implementation of map itself is thread-safe, then no matter how you operate inside multi-threads, it will be fine. (Even if it is declared in the main thread and passed by reference to the child thread)

    For specific popular science knowledge about thread safety, you can read the articles I wrote before https://zhuanlan.zhihu.com/p/...

    reply
    0
  • PHPz

    PHPz2017-04-18 10:51:12

    How to put it, it’s like:
    You put your money in your suitcase and walk down the street alone.
    You think it’s safe, of course.
    But once it is robbed, it is not safe. . .

    Thread safety means that different threads access the same data. If there is only one thread, there is no thread safety. Or you can also understand it as "safe", after all, no other objects can access it, but it is not "thread safe"

    Answer the question:

    Is this map object thread-unsafe?

    Yes, it is not thread-safe.
    Because although each Thread object here has a unique and independent Map object, it does not have "thread safety capabilities".
    Well, this is my understanding, it seems a bit verbose. . . ==

    reply
    0
  • 高洛峰

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

    Thanks for the invitation!
    Limited usage in to new MyThread().start()的情况下是线程安全.

    reply
    0
  • 迷茫

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

    Although you declared it private, you can still read the variable in another thread. Without a synchronization lock, it is thread unsafe.

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

    reply
    0
  • 迷茫

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

    Reading is no problem, writing will cause thread safety issues. . .

    1. Use thread-safe class methods

    2. Use ThreadLocal

    reply
    0
  • PHPz

    PHPz2017-04-18 10:51:12

    Think of MyThread只是看成一个类(别想它是一个线程类),把obj just as a member of this class. Then it becomes easier to understand.

    reply
    0
  • 伊谢尔伦

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

    In case of 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();

    reply
    0
  • PHPz

    PHPz2017-04-18 10:51:12

    It mainly depends on whether you have accessed a certain public resource. This question does not involve accessing a certain public resource, so it cannot be said to be safe or unsafe.

    reply
    0
  • PHP中文网

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

    It mainly depends on whether you have operated on this variable, and assuming that you come out with a new object every time, it is thread-safe.

    reply
    0
  • Cancelreply