亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

關于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 關注
  • 2539 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號