jvm - Java new 物件是否是原子性的?
滿天的星座
滿天的星座 2017-06-23 09:14:17
0
4
1291
public static void main(Sting args[]){
     Object a=null;
     new Thread(){
              a=new xxx()
     }.start();

     new Thread(){
              a=new xxx()
     }.start();
}

想問,xxx()方法裡有複雜的對像初始化邏輯,new關鍵字創建對象,是原子性的嗎?如果不是,會不會就出現了物件初始化錯亂的問題?

滿天的星座
滿天的星座

全部回覆(4)
扔个三星炸死你

沒懂你的意思,如果我猜得不錯的話:

這完全取決於你的構造方法裡面的具體的邏輯,畢竟程式碼是人寫的。

public class Test {
    static class A{
        public A(){
            try {
                SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd:hh:mm:ss:SS");
                System.out.println(sdf.format(new Date()) + "--begin --从线程" + Thread.currentThread().getName() + "中创建A");
                Thread.sleep(2000);
                System.out.println(sdf.format(new Date()) + "--end--从线程" + Thread.currentThread().getName() + "中创建A");
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
    
    public static void main(String[] args) {
        new Thread(new Runnable(){

            @Override
            public void run() {
                System.out.println("A is " +new A());
            }
            
        }).start();
        
        new Thread(new Runnable(){

            @Override
            public void run() {
                System.out.println("A is " +new A());
            }
            
        }).start();
    }
}

輸出:

2017-06-16:11:46:43:780--begin --从线程Thread-1中创建A
2017-06-16:11:46:43:780--begin --从线程Thread-0中创建A
2017-06-16:11:46:45:786--end--从线程Thread-0中创建A
2017-06-16:11:46:45:786--end--从线程Thread-1中创建A
A is nwe.Test$A@1e6a629c
A is nwe.Test$A@27fcb25d

另一個例子,構造器中包含同步區塊,每一個執行緒都需要等待前面的執行緒執行完成後才能執行。

import java.text.*;
import java.util.Date;

public class Test {
    static class A{
        public A(){
            try {
                synchronized (Test.class) {
                    SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd:hh:mm:ss:SS");
                    System.out.println(sdf.format(new Date()) + "--begin --从线程" + Thread.currentThread().getName() + "中创建A");
                    Thread.sleep(2000);
                    System.out.println(sdf.format(new Date()) + "--end--从线程" + Thread.currentThread().getName() + "中创建A");
                }
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
    
    public static void main(String[] args) {
        new Thread(new Runnable(){

            @Override
            public void run() {
                System.out.println("A is " +new A());
            }
            
        }).start();
        
        new Thread(new Runnable(){

            @Override
            public void run() {
                System.out.println("A is " +new A());
            }
            
        }).start();
    }
}

輸出:

2017-06-16:11:49:33:548--begin --从线程Thread-0中创建A
2017-06-16:11:49:35:549--end--从线程Thread-0中创建A
A is nwe.Test$A@717c3e10
2017-06-16:11:49:35:550--begin --从线程Thread-1中创建A
2017-06-16:11:49:37:553--end--从线程Thread-1中创建A
A is nwe.Test$A@27280786
淡淡烟草味

建議參考線程安全的單例模式

扔个三星炸死你

不具有,例如在構造方法中寫了多個邏輯,在執行構造方法時,是可以中斷的。

洪涛

「原子性」這種描述太抽象,樓主提問的時候最好不要認為所有人對某個字的認識都完全一樣。我只能說構造方法是線程安全的,對於每一個對象,構造方法只會被執行一次,只會被一個線程執行。

熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板