素材牛VIP会员
关于java的多线程的成员变量是否线程安全的疑问?
 多***悟  分类:Java代码  人气:1759  回帖:14  发布于6年前 收藏

对于下面的程序:

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

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

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

讨论这个帖子(14)垃圾回帖将一律封号处理……

Lv 牛魔王
素材牛 PHP开发工程师 6年前#1

线程安全的概述是指当多个线程访问同一个对象时,如果不用考虑这些线程在运行时环境下的调度和交替运行,也不需要进行额外的同步,或者在调用方进行任何其他的协调操作,调用这个对象的行为都可以获取正确的结果。
判断多线程的安全可以从以下三点分析:

1.明确哪些代码是多线程运行的代码, 
2.明确共享数据,
3.明确多线程运行代码中哪些语句是操作共享数据.

如果多个线程操作一个共享数据,就要考虑线程安全问题。

Lv6 码匠
生***炸 UI设计师 6年前#2

怎么说呢,这就好比:
你把钱装在了手提箱里,一个人走在街上。
你觉得这是安全的,当然了。
但是一旦被抢,就不安全了。。。

线程安全说的是不同线程访问同一个数据,如果只存在一个线程,就谈不上什么线程安不安全。或者你也可以理解为是“安全”的,毕竟没有其他对象来访问,但是不是“线程安全”

回答一下问题:

这个map对象,是线程不安全的吗?

是的,线程不安全。
因为虽然这里每个Thread对象都拥有唯一独立的Map对象,可是却没有“线程安全的能力”。
嘛,我的理解就是这样的,好像有点啰嗦了。。。==

Lv5 码农
sh***ao 职业无 6年前#3

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

Lv2 入门
蒙***生 职业无 6年前#4

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

虽然你定义的是 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
Lv1 新人
闪***星 UI设计师 6年前#5

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

1、用线程安全的类方法

2、用ThreadLocal

Lv7 码师
un***oo 职业无 6年前#6

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

Lv6 码匠
素***2 学生 6年前#7

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

Lv1 新人
冷***知 职业无 6年前#8

你的理解是正确的,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();
Lv1 新人
真***溜 职业无 6年前#9

每次都是new了新对象,那么,他里面的这个map就是这个对象自己拥有的,所以,是安全的。

这句话是没错的,除非你在调用子线程的这个主线程中声明了公共成员(变量)并且在子线程内部操作了这个公共变量,或者你把这个公共变量按引用传递进了子线程内部并且在子线程内部操作了它,这样才会导致线程不安全问题的出现,至于map类型本身是不是线程安全我也忘了(我记得map是一个接口,是否为线程安全要看他的具体实现把),你百度一下把。。。

如果map的实现本身是线程安全,那么无论你在多线程内部怎么操作都是没事的。(即使他在主线程中声明并且按引用传入了子线程中)

具体线程安全科普知识可以看看我以前写过的文章https://zhuanlan.zhihu.com/p/...

Lv7 码师
封***榜 职业无 6年前#10

在多线程的情况下

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();
上一页12下一页
 文明上网,理性发言!   😉 阿里云幸运券,戳我领取