为了账号安全,请及时绑定邮箱和手机立即绑定

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

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

长风秋雁 2019-02-21 08:05:06
对于下面的程序: public class MyThread extends Thread{ private Object obj; ...... } 请问,这个MyThread里面的成员变量,是不是线程安全的? 因为,MyThread继承了Thread,其使用方式为:new MyThread().start();所以,这就意味着,每次都是new了新对象,那么,他里面的各个成员变量就是这个对象自己拥有的,所以,是安全的。我这样理解有问题吗?
查看完整描述

14 回答

?
慕标琳琳

TA贡献1830条经验 获得超9个赞

线程安全与否和是否在多个线程中使用有关

虽然你定义的是 private,但有很多种方法都可以在其它线程中间接的访问到它,所以它存在在多个线程中使用的可能,但是代码里又没有加入同步处理,所以它是不安全的。

补充

使用 Thread 和 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--);
            }
        }
    }
}

一个不案例的运行示例(要多运行几次才遇得到)

thread: 10
thread: 9
thread: 7
thread: 10
thread: 6
thread: 8
thread: 3
thread: 4
thread: 5
thread: 1
thread: 2
查看完整回答
反对 回复 2019-03-01
?
三国纷争

TA贡献1804条经验 获得超7个赞

谢邀!
限定使用方式为new MyThread().start()的情况下是线程安全的。

查看完整回答
反对 回复 2019-03-01
?
慕码人2483693

TA贡献1860条经验 获得超9个赞

虽然你声明的private但还是可以在另一个线程里读取该变量,在没有加同步锁的情况下就是线程不安全的。

题主想的这种线程安全的变量应该是在run方法里面声明的,这样的话对象就存在于线程工作内存里独享。
查看完整回答
反对 回复 2019-03-01
?
holdtom

TA贡献1805条经验 获得超10个赞

读没问题,写会出现线程安全问题。。。

1、用线程安全的类方法

2、用ThreadLocal

查看完整回答
反对 回复 2019-03-01
?
慕侠2389804

TA贡献1719条经验 获得超6个赞

MyThread只是看成一个类(别想它是一个线程类),把obj只是看成这个类的成员。然后就好理解了。

查看完整回答
反对 回复 2019-03-01
?
缥缈止盈

TA贡献2041条经验 获得超4个赞

在多线程的情况下

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();
查看完整回答
反对 回复 2019-03-01
?
侃侃无极

TA贡献2051条经验 获得超10个赞

主要看你有没有访问某一个公共资源,lz这个问题,没有涉及到访问某个公共资源,所以谈不上安全不安全。

查看完整回答
反对 回复 2019-03-01
?
慕无忌1623718

TA贡献1744条经验 获得超4个赞

主要是看你有木有对这个变量进行操作,而且假设你每次都是new一个对象出来,就是线程安全的。

查看完整回答
反对 回复 2019-03-01
?
慕村225694

TA贡献1880条经验 获得超4个赞

就单纯你说的这个情况,肯定是线程安全的,因为只有你自己线程使用.

查看完整回答
反对 回复 2019-03-01
?
浮云间

TA贡献1829条经验 获得超4个赞

你的理解是正确的,new MyThread().start() 每次都是new Thread 对象来启动线程,不存在共享行为,所以是线程安全的,最高票的答案

MyThread mt = new MyThread(); // 这里只 new 了一个对象,然后多线程操作,会存在线程安全问题
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();
查看完整回答
反对 回复 2019-03-01
?
拉风的咖菲猫

TA贡献1995条经验 获得超2个赞

一个简单的例子
如果你有一个糖果 别人都想吃 那么就是不安全,这样你就发现你需要一个盒子和锁把它锁起来

查看完整回答
反对 回复 2019-03-01
  • 14 回答
  • 0 关注
  • 2552 浏览

添加回答

举报

0/150
提交
取消
微信客服

购课补贴
联系客服咨询优惠详情

帮助反馈 APP下载

慕课网APP
您的移动学习伙伴

公众号

扫描二维码
关注慕课网微信公众号