Java

關(guān)鍵字

static

靜態(tài)內(nèi)部類與非靜態(tài)內(nèi)部類之間存在一個最大的區(qū)別:
非靜態(tài)內(nèi)部類在編譯完成之后會隱含地保存著一個引用,該引用是指向創(chuàng)建它的外圍內(nèi),但是靜態(tài)內(nèi)部類卻沒有。沒有這個引用就意味著:
1.它的創(chuàng)建是不需要依賴外圍類的創(chuàng)建。
2.它不能使用任何外圍類的非static成員變量和方法。

匿名內(nèi)部類和其他.

1.內(nèi)部類概述和訪問特點

A:內(nèi)部類概述:
把類定義在其他類的內(nèi)部,這個類就被稱為內(nèi)部類。
舉例:在類A中定義了一個類B,類B就是內(nèi)部類。
B:內(nèi)部類訪問特點
a:內(nèi)部類可以直接訪問外部類的成員,包括私有。
b:外部類要訪問內(nèi)部類的成員,必須創(chuàng)建對象。

多線程

創(chuàng)建方式

public class ThreadDemo {
    public static void main(String[] args) {
        // 創(chuàng)建對象
        MyThread t1 = new MyThread() ;
        MyThread t2 = new MyThread() ;
        // 啟動線程: 需要使用start方法啟動線程, 如果我們在這里調(diào)用的是run方法,那么我們只是把該方法作為普通方法進行執(zhí)行
//      t1.run() ;
//      t1.run() ;
        t1.start() ;        // 告訴jvm開啟一個線程調(diào)用run方法
        // t1.start() ;     // 一個線程只能被啟動一次
        t2.start() ;
        
    }
}

public class MyThread extends Thread {
    @Override
    public void run() {
        for(int x = 0 ; x < 1000 ; x++) {
            System.out.println(x);
        }
    }
}
public static void main(String[] args) {
    // 創(chuàng)建定義的類的對象
    MyThread mt = new MyThread() ;
    // 創(chuàng)建Thread的對象吧第三步創(chuàng)建的對象作為參數(shù)傳遞進來
    Thread t1 = new Thread(mt , "張三") ;
    Thread t2 = new Thread(mt , "李四") ;
    // 啟動線程
    t1.start() ;
    t2.start() ;
}

public class MyThread implements Runnable {
    @Override
    public void run() {
        for(int x = 0 ; x < 1000 ; x++) {
            System.out.println(Thread.currentThread().getName() + "---" + x);
        }
        
    }
}

細節(jié)

1.run()和start()方法的區(qū)別
啟動線程: 需要使用start方法啟動線程, 如果我們在這里調(diào)用的是run方法,那么我們只是把該方法作為普通方法進行執(zhí)行。
2.一個線程只能被啟動一次

匿名內(nèi)部類方式

new Thread(){代碼…}.start();
new Thread(new Runnable(){代碼…}).start();

線程調(diào)度

線程有兩種調(diào)度模型

  1. 分時調(diào)度模型
    所有線程輪流使用CPU的使用權(quán),平均分配每個線程占用 CPU 的時間片
  2. 搶占式調(diào)度模型
    優(yōu)先讓優(yōu)先級高的線程使用 CPU,如果線程的優(yōu)先級相同,那么會隨機選擇一個,優(yōu)先級高的線程獲取的 CPU 時間片相對多一些。Java使用的是搶占式調(diào)度模型

線程控制

image.png
  1. 線程控制之休眠線程
  • public static void sleep(long time) ;
    time表達的意思是休眠的時間 , 單位是毫秒
  1. 線程控制之加入線程
  • public final void join()
    等待該線程執(zhí)行完畢了以后,其他線程才能再次執(zhí)行
    注意事項: 在線程啟動之后,在調(diào)用方法
  1. 線程控制之禮讓線程
  • public static void yield():
    暫停當前正在執(zhí)行的線程對象,并執(zhí)行其他線程。
    線程禮讓的原理是: 暫定當前的線程,然CPU去執(zhí)行其他的線程, 這個暫定的時間是相當短暫的; 當我某一個線程暫定完畢以后,其他的線程還沒有搶占到cpu的執(zhí)行權(quán) ; 那么這個是時候當前的線程會和其他的線程再次搶占cpu的執(zhí)行權(quán);
  1. 線程控制之守護線程
  • public final void setDaemon(boolean on)
    將該線程標記為守護線程或用戶線程。當正在運行的線程都是守護線程時,Java 虛擬機退出。 該方法必須在啟動線程前調(diào)用。
    jvm會線程程序中存在的線程類型,如果線程全部是守護線程,那么jvm就停止。
  1. 線程控制之中斷線程
  • public final void stop():
    停止線程的運行
    public void interrupt():
    中斷線程(這個翻譯不太好),查看API可得當線程調(diào)用wait(),sleep(long time)方法的時候處于阻塞狀態(tài),可以通過這個方法清除阻塞
  • wait()和sleep()的區(qū)別
    sleep來自Thread類,和wait來自O(shè)bject類
    調(diào)用sleep()方法的過程中,線程不會釋放對象鎖。而 調(diào)用 wait 方法線程會釋放對象鎖
    sleep睡眠后不會讓系統(tǒng)資源,wait讓出系統(tǒng)資源其他線程可以占用CPU
    sleep(milliseconds)需要指定一個睡眠時間,時間一到會自動喚醒

同步互斥鎖

synchronized的使用

  • synchronized代碼塊,被修飾的代碼成為同步語句塊,其作用的范圍是調(diào)用這個代碼塊的對象,我們在用synchronized關(guān)鍵字的時候,能縮小代碼段的范圍就盡量縮小,能在代碼段上加同步就不要再整個方法上加同步。這叫減小鎖的粒度,使代碼更大程度的并發(fā)。

  • synchronized方法,被修飾的方法成為同步方法,其作用范圍是整個方法,作用對象是調(diào)用這個方法的對象。

  • synchronized靜態(tài)方法,修飾一個static靜態(tài)方法,其作用范圍是整個靜態(tài)方法,作用對象是這個類的所有對象。

  • synchronized類,其作用范圍是Synchronized后面括號括起來的部分synchronized(className.class),作用的對象是這個類的所有對象。

  • synchronized(),()中是鎖住的對象, synchronized(this)鎖住的只是對象本身,同一個類的不同對象調(diào)用的synchronized方法并不會被鎖住,而synchronized(className.class)實現(xiàn)了全局鎖的功能,所有這個類的對象調(diào)用這個方法都受到鎖的影響,此外()中還可以添加一個具體的對象,實現(xiàn)給具體對象加鎖。

注意的點

  • 當兩個并發(fā)線程訪問同一個對象object中的這個synchronized(this)同步代碼塊時,一個時間內(nèi)只能有一個線程得到執(zhí)行。另一個線程必須等待當前線程執(zhí)行完這個代碼塊以后才能執(zhí)行該代碼塊。
public class Thread1 implements Runnable {  
     public void run() {  
          synchronized(this) {  
               for (int i = 0; i < 5; i++) {  
                    System.out.println(Thread.currentThread().getName() + " synchronized loop " + i);  
               }  
          }  
     }  
     public static void main(String[] args) {  
          Thread1 t1 = new Thread1();  
          Thread ta = new Thread(t1, "A");  
          Thread tb = new Thread(t1, "B");  
          ta.start();  
          tb.start();  
     } 
}
//輸出
A synchronized loop 0  
A synchronized loop 1  
A synchronized loop 2  
A synchronized loop 3  
A synchronized loop 4  
B synchronized loop 0  
B synchronized loop 1  
B synchronized loop 2  
B synchronized loop 3  
B synchronized loop 4

  • 當一個線程訪問object的一個synchronized(this)同步代碼塊時,另一個線程仍然可以訪問該object中的非synchronized(this)同步代碼塊。(兩個線程使用的是同一個對象)
public class Thread2 {  
     public void m4t1() {  
          synchronized(this) {  
               int i = 5;  
               while( i-- > 0) {  
                    System.out.println(Thread.currentThread().getName() + " : " + i);  
                    try {  
                         Thread.sleep(500);  
                    } catch (InterruptedException ie) {  
                    }  
               }  
          }  
     }  
     public void m4t2() {  
          int i = 5;  
          while( i-- > 0) {  
               System.out.println(Thread.currentThread().getName() + " : " + i);  
               try {  
                    Thread.sleep(500);  
               } catch (InterruptedException ie) {  
               }  
          }  
     }  
     public static void main(String[] args) {  
          final Thread2 myt2 = new Thread2();  
          Thread t1 = new Thread(  new Runnable() {  public void run() {  myt2.m4t1();  }  }, "t1"  );  
          Thread t2 = new Thread(  new Runnable() {  public void run() { myt2.m4t2();   }  }, "t2"  );  
          t1.start();  
          t2.start();  
     } 
}
//輸出
t1 : 4  
t2 : 4  
t1 : 3  
t2 : 3  
t1 : 2  
t2 : 2  
t1 : 1  
t2 : 1  
t1 : 0  
t2 : 0
  • 當一個線程訪問object的一個synchronized(this)同步代碼塊時,其他線程對object中所有其它synchronized(this)同步代碼塊的訪問將被阻塞(同上,兩個線程使用的是同一個對象)。
//修改Thread2.m4t2()方法:  
     public void m4t2() {  
          synchronized(this) {  
               int i = 5;  
               while( i-- > 0) {  
                    System.out.println(Thread.currentThread().getName() + " : " + i);  
                    try {  
                         Thread.sleep(500);  
                    } catch (InterruptedException ie) {  
                    }  
               }  
          }

     }
//此種寫法也一樣
//修改Thread2.m4t2()方法如下:

     public synchronized void m4t2() {  
          int i = 5;  
          while( i-- > 0) {  
               System.out.println(Thread.currentThread().getName() + " : " + i);  
               try {  
                    Thread.sleep(500);  
               } catch (InterruptedException ie) {  
               }  
          }  
     }
//輸出
t1 : 4  
t1 : 3  
t1 : 2  
t1 : 1  
t1 : 0  
t2 : 4  
t2 : 3  
t2 : 2  
t2 : 1  
t2 : 0

  • 類鎖與對象鎖不互斥
public class Test {
 
    public static void main(String[] args)  {
        final InsertData insertData = new InsertData();
        new Thread(){
            @Override
            public void run() {
                insertData.insert();
            }
        }.start(); 
        new Thread(){
            @Override
            public void run() {
                insertData.insert1();
            }
        }.start();
    }  
}
 
class InsertData { 
    public synchronized void insert(){
        System.out.println("執(zhí)行insert");
        try {
            Thread.sleep(5000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("執(zhí)行insert完畢");
    }
     
    public synchronized static void insert1() {
        System.out.println("執(zhí)行insert1");
        System.out.println("執(zhí)行insert1完畢");
    }
}

volatile關(guān)鍵字

Java內(nèi)存分配機制及內(nèi)存泄漏

Java類加載機制

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 1. Java基礎(chǔ)部分 基礎(chǔ)部分的順序:基本語法,類相關(guān)的語法,內(nèi)部類的語法,繼承相關(guān)的語法,異常的語法,線程的語...
    子非魚_t_閱讀 34,644評論 18 399
  • 進程和線程 進程 所有運行中的任務(wù)通常對應(yīng)一個進程,當一個程序進入內(nèi)存運行時,即變成一個進程.進程是處于運行過程中...
    勝浩_ae28閱讀 5,257評論 0 23
  • 2XX(Success 成功狀態(tài)碼) 2XX 響應(yīng)的結(jié)果標明請求被正常處理了 200 OK 表示從客戶端發(fā)來的請求...
    騎摩托馬斯閱讀 451評論 0 2
  • 在使用ansible時,遇到下面的報錯 原因是此主機之前沒有ssh連接過,在本機的~/.ssh/known_hos...
    金琥閱讀 1,517評論 0 1
  • 賀縣詩詞協(xié)會成立三十周年 文/雪吟疏影 一湖澄碧自漪淪,夾岸參差綠樹陰。 涵泳卅年唐宋夢,濯除百世利名心。 青...
    雪吟疏影閱讀 475評論 0 0

友情鏈接更多精彩內(nèi)容