對于下面的程序:
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

慕碼人2483693
TA貢獻1860條經驗 獲得超9個贊
雖然你聲明的private但還是可以在另一個線程里讀取該變量,在沒有加同步鎖的情況下就是線程不安全的。
題主想的這種線程安全的變量應該是在run方法里面聲明的,這樣的話對象就存在于線程工作內存里獨享。

縹緲止盈
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();

浮云間
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();
添加回答
舉報
0/150
提交
取消