1. 程式人生 > >1.java一切即物件以及java記憶體模型與執行緒

1.java一切即物件以及java記憶體模型與執行緒

由此可以得知:

程式碼完成之後進行本地配置的一些讀取操作:

至此可以得知其編譯模式是mixed模式的

new date()預設輸出的結果是import中包的預設建構函式初始化後的結果:

觀看Date類原始碼即可得知:

鑑於java是單繼承關係,由此來看一下import的傳遞過程,如下所示:

如下所示:


 

volatile運算;

/**
 * volatile變數自增運算測試
 * @author=hss
 */
public class Volatile {
    public static volatile int race = 0;

    public static void increase() {
        race++;
    }

    private static final int THREADS_COUNRT = 20;

    public static void main(String[] args) {
        Thread[] threads = new Thread[THREADS_COUNRT];//發起了20個執行緒操作
        for (int i = 0; i < THREADS_COUNRT; i++) { //遍歷每個生成的執行緒操作
            threads[i] = new Thread(new Runnable() { //對每一個執行緒執行runable介面的例項化的run()方法
                @Override
                public void run() {
                    for (int i = 0; i < 10000; i++) { //對於每一個單個執行緒執行1000次自增的操作
                        increase(); //呼叫increase()方法實現內部呼叫,也就是迭代
                    }
                }
            });
            threads[i].start();//啟動20個執行緒中的一個
            System.out.println("這是第"+i+"執行緒");
        }
        //等待所有累加執行緒都結束
        while(Thread.activeCount()>1)
            Thread.yield();//yield是實現一個runable介面的方法
        System.out.println(race);//最後輸出race裡面的自增的次數。
    }
}

輸出的結果如下:

"C:\Program Files\Java\jdk1.8.0_171\bin\java.exe" -agentlib:jdwp=transport=dt_socket,address=127.0.0.1:64780,suspend=y,server=n -javaagent:C:\Users\wu\.IntelliJIdea2018.2\system\captureAgent\debugger-agent.jar=file:/C:/Users/wu/AppData/Local/Temp/capture.props -Dfile.encoding=UTF-8 -classpath "C:\Program Files\Java\jdk1.8.0_171\jre\lib\charsets.jar;C:\Program Files\Java\jdk1.8.0_171\jre\lib\deploy.jar;C:\Program Files\Java\jdk1.8.0_171\jre\lib\ext\access-bridge-64.jar;C:\Program Files\Java\jdk1.8.0_171\jre\lib\ext\cldrdata.jar;C:\Program Files\Java\jdk1.8.0_171\jre\lib\ext\dnsns.jar;C:\Program Files\Java\jdk1.8.0_171\jre\lib\ext\jaccess.jar;C:\Program Files\Java\jdk1.8.0_171\jre\lib\ext\jfxrt.jar;C:\Program Files\Java\jdk1.8.0_171\jre\lib\ext\localedata.jar;C:\Program Files\Java\jdk1.8.0_171\jre\lib\ext\nashorn.jar;C:\Program Files\Java\jdk1.8.0_171\jre\lib\ext\sunec.jar;C:\Program Files\Java\jdk1.8.0_171\jre\lib\ext\sunjce_provider.jar;C:\Program Files\Java\jdk1.8.0_171\jre\lib\ext\sunmscapi.jar;C:\Program Files\Java\jdk1.8.0_171\jre\lib\ext\sunpkcs11.jar;C:\Program Files\Java\jdk1.8.0_171\jre\lib\ext\zipfs.jar;C:\Program Files\Java\jdk1.8.0_171\jre\lib\javaws.jar;C:\Program Files\Java\jdk1.8.0_171\jre\lib\jce.jar;C:\Program Files\Java\jdk1.8.0_171\jre\lib\jfr.jar;C:\Program Files\Java\jdk1.8.0_171\jre\lib\jfxswt.jar;C:\Program Files\Java\jdk1.8.0_171\jre\lib\jsse.jar;C:\Program Files\Java\jdk1.8.0_171\jre\lib\management-agent.jar;C:\Program Files\Java\jdk1.8.0_171\jre\lib\plugin.jar;C:\Program Files\Java\jdk1.8.0_171\jre\lib\resources.jar;C:\Program Files\Java\jdk1.8.0_171\jre\lib\rt.jar;C:\Users\wu\Desktop\work\11\vue\java_traing\out\production\java_traing;D:\IDEA_JAVA\IntelliJ IDEA 2018.2.4\lib\idea_rt.jar" Volatile
Connected to the target VM, address: '127.0.0.1:64780', transport: 'socket'
這是第0執行緒
這是第1執行緒
這是第2執行緒
這是第3執行緒
這是第4執行緒
這是第5執行緒
這是第6執行緒
這是第7執行緒
這是第8執行緒
這是第9執行緒
這是第10執行緒
這是第11執行緒
這是第12執行緒
這是第13執行緒
這是第14執行緒
這是第15執行緒
這是第16執行緒
這是第17執行緒
這是第18執行緒
這是第19執行緒
Disconnected from the target VM, address: '127.0.0.1:64780', transport: 'socket'
188320

Process finished with exit code 0

 

再一次輸出結果如下:

"C:\Program Files\Java\jdk1.8.0_171\bin\java.exe" -agentlib:jdwp=transport=dt_socket,address=127.0.0.1:64956,suspend=y,server=n -javaagent:C:\Users\wu\.IntelliJIdea2018.2\system\captureAgent\debugger-agent.jar=file:/C:/Users/wu/AppData/Local/Temp/capture.props -Dfile.encoding=UTF-8 -classpath "C:\Program Files\Java\jdk1.8.0_171\jre\lib\charsets.jar;C:\Program Files\Java\jdk1.8.0_171\jre\lib\deploy.jar;C:\Program Files\Java\jdk1.8.0_171\jre\lib\ext\access-bridge-64.jar;C:\Program Files\Java\jdk1.8.0_171\jre\lib\ext\cldrdata.jar;C:\Program Files\Java\jdk1.8.0_171\jre\lib\ext\dnsns.jar;C:\Program Files\Java\jdk1.8.0_171\jre\lib\ext\jaccess.jar;C:\Program Files\Java\jdk1.8.0_171\jre\lib\ext\jfxrt.jar;C:\Program Files\Java\jdk1.8.0_171\jre\lib\ext\localedata.jar;C:\Program Files\Java\jdk1.8.0_171\jre\lib\ext\nashorn.jar;C:\Program Files\Java\jdk1.8.0_171\jre\lib\ext\sunec.jar;C:\Program Files\Java\jdk1.8.0_171\jre\lib\ext\sunjce_provider.jar;C:\Program Files\Java\jdk1.8.0_171\jre\lib\ext\sunmscapi.jar;C:\Program Files\Java\jdk1.8.0_171\jre\lib\ext\sunpkcs11.jar;C:\Program Files\Java\jdk1.8.0_171\jre\lib\ext\zipfs.jar;C:\Program Files\Java\jdk1.8.0_171\jre\lib\javaws.jar;C:\Program Files\Java\jdk1.8.0_171\jre\lib\jce.jar;C:\Program Files\Java\jdk1.8.0_171\jre\lib\jfr.jar;C:\Program Files\Java\jdk1.8.0_171\jre\lib\jfxswt.jar;C:\Program Files\Java\jdk1.8.0_171\jre\lib\jsse.jar;C:\Program Files\Java\jdk1.8.0_171\jre\lib\management-agent.jar;C:\Program Files\Java\jdk1.8.0_171\jre\lib\plugin.jar;C:\Program Files\Java\jdk1.8.0_171\jre\lib\resources.jar;C:\Program Files\Java\jdk1.8.0_171\jre\lib\rt.jar;C:\Users\wu\Desktop\work\11\vue\java_traing\out\production\java_traing;D:\IDEA_JAVA\IntelliJ IDEA 2018.2.4\lib\idea_rt.jar" Volatile
Connected to the target VM, address: '127.0.0.1:64956', transport: 'socket'
這是第0執行緒
這是第1執行緒
這是第2執行緒
這是第3執行緒
這是第4執行緒
這是第5執行緒
這是第6執行緒
這是第7執行緒
這是第8執行緒
這是第9執行緒
這是第10執行緒
這是第11執行緒
這是第12執行緒
這是第13執行緒
這是第14執行緒
這是第15執行緒
這是第16執行緒
這是第17執行緒
這是第18執行緒
這是第19執行緒
Disconnected from the target VM, address: '127.0.0.1:64956', transport: 'socket'
157513

Process finished with exit code 0

 

顯示輸出結果發生了變化從188320變成了157513

也就是程式碼片段的race的值:

按照程式碼邏輯的值,實際上是應該生成20(執行緒數目)*10000(i《10000,單個執行緒自增的次數)使用yield中的group進行執行緒集合統計:

正確併發結果,結果應該是200000才對,但是實際結果並不是這樣:

1>不僅僅是不會等於200000,而且都是小於200000的。

當getstatic(初始化關鍵字)和new的作用是類似的,用於進行初始化操作的,

當gestatic指令把race的值取到操作棧頂時,volatile關鍵字保證了race在此時時正確的,

但是在執行iconst_1,iadd這些指令的時候,其他執行緒已經把race的值加大了,而在操作棧頂的值就變成了過期的資料,所以putstatic指令執行後就可能把較小的race值同步回主記憶體中了,導致

race的值總是小於200000

因此使用vlolatitle是不安全的。