最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

JAVA面試題 簡(jiǎn)談你對(duì)synchronized關(guān)鍵字的理解

 更新時(shí)間:2019年07月24日 08:31:36   作者:Java螞蟻  
這篇文章主要介紹了JAVA面試題 請(qǐng)談?wù)勀銓?duì)Sychronized關(guān)鍵字的理解,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下

面試官:sychronized關(guān)鍵字有哪些特性?

應(yīng)聘者:

  • 可以用來(lái)修飾方法;
  • 可以用來(lái)修飾代碼塊;
  • 可以用來(lái)修飾靜態(tài)方法;
  • 可以保證線程安全;
  • 支持鎖的重入;
  • sychronized使用不當(dāng)導(dǎo)致死鎖;

了解sychronized之前,我們先來(lái)看一下幾個(gè)常見的概念:內(nèi)置鎖、互斥鎖、對(duì)象鎖和類鎖。

內(nèi)置鎖

在Java中每一個(gè)對(duì)象都可以作為同步的鎖,那么這些鎖就被稱為內(nèi)置鎖。線程進(jìn)入同步代碼塊或方法的時(shí)候會(huì)自動(dòng)獲得該鎖,在退出同步代碼塊或方法時(shí)會(huì)釋放該鎖。獲得內(nèi)置鎖的唯一途徑就是進(jìn)入這個(gè)鎖的保護(hù)的同步代碼塊或方法。

互斥鎖

內(nèi)置鎖同時(shí)也是一個(gè)互斥鎖,這就是意味著最多只有一個(gè)線程能夠獲得該鎖,當(dāng)線程A嘗試去獲得線程B持有的內(nèi)置鎖時(shí),線程A必須等待或者阻塞,直到線程B拋出異?;蛘哒?zhí)行完畢釋放這個(gè)鎖;如果B線程不釋放這個(gè)鎖,那么A線程將永遠(yuǎn)等待下去。

對(duì)象鎖和類鎖

對(duì)象鎖和類鎖在鎖的概念上基本上和內(nèi)置鎖是一致的,但是,兩個(gè)鎖實(shí)際是有很大的區(qū)別的。

  • 對(duì)象鎖是用于對(duì)象實(shí)例方法;
  • 類鎖是用于類的靜態(tài)方法或者一個(gè)類的class對(duì)象上的

一個(gè)對(duì)象無(wú)論有多少個(gè)同步方法區(qū),它們共用一把鎖,某一時(shí)刻某個(gè)線程已經(jīng)進(jìn)入到某個(gè)synchronzed方法,那么在該方法沒有執(zhí)行完畢前,其他線程無(wú)法訪問該對(duì)象的任何synchronzied 方法的,但可以訪問非synchronzied方法。

如果synchronized方法是static的,那么當(dāng)線程訪問該方法時(shí),它鎖的并不是synchronized方法所在的對(duì)象,而是synchronized方法所在對(duì)象的對(duì)應(yīng)的Class對(duì)象,

因?yàn)閖ava中無(wú)論一個(gè)類有多少個(gè)對(duì)象,這些對(duì)象會(huì)對(duì)應(yīng)唯一一個(gè)Class對(duì)象,因此當(dāng)線程分別訪問同一個(gè)類的兩個(gè)對(duì)象的static,synchronized方法時(shí),他們的執(zhí)行也是按順序來(lái)的,也就是說(shuō)一個(gè)線程先執(zhí)行,一個(gè)線程后執(zhí)行。

synchronized的用法:修飾方法和修飾代碼塊,下面分別分析這兩種用法在對(duì)象鎖和類鎖上的效果。

對(duì)象鎖的synchronized修飾方法和代碼塊

public class TestSynchronized {
  public void test1() {
    synchronized (this) {
      int i = 5;
      while (i-- > 0) {
        System.out.println(Thread.currentThread().getName() + " : " + i);
        try {
          Thread.sleep(500);
        } catch (InterruptedException ie) {
        }
      }
    }
  }
 
  public synchronized void test2() {
    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 TestSynchronized myt2 = new TestSynchronized();
    Thread test1 = new Thread(new Runnable() {
      public void run() {
        myt2.test1();
      }
    }, "test1");
    Thread test2 = new Thread(new Runnable() {
      public void run() {
        myt2.test2();
      }
    }, "test2");
    test1.start();
    test2.start();
  }
}

打印結(jié)果如下:

test2 : 4
test2 : 3
test2 : 2
test2 : 1
test2 : 0
test1 : 4
test1 : 3
test1 : 2
test1 : 1
test1 : 0

上述的代碼,第一個(gè)方法用了同步代碼塊的方式進(jìn)行同步,傳入的對(duì)象實(shí)例是this,表明是當(dāng)前對(duì)象;第二個(gè)方法是修飾方法的方式進(jìn)行同步

。因?yàn)榈谝粋€(gè)同步代碼塊傳入的this,所以兩個(gè)同步代碼所需要獲得的對(duì)象鎖都是同一個(gè)對(duì)象鎖,下面main方法時(shí)分別開啟兩個(gè)線程,分別調(diào)用test1和test2方法,那么兩個(gè)線程都需要獲得該對(duì)象鎖,另一個(gè)線程必須等待。

上面也給出了運(yùn)行的結(jié)果可以看到:直到test2線程執(zhí)行完畢,釋放掉鎖,test1線程才開始執(zhí)行。這里test2方法先搶到CPU資源,故它先執(zhí)行,它獲得了鎖,它執(zhí)行完畢后,test1才開始執(zhí)行。

如果我們把test2方法的synchronized關(guān)鍵字去掉,執(zhí)行結(jié)果會(huì)如何呢? 

test1 : 4
test2 : 4
test2 : 3
test2 : 2
test2 : 1
test2 : 0
test1 : 3
test1 : 2
test1 : 1
test1 : 0

我們可以看到,結(jié)果輸出是交替著進(jìn)行輸出的,這是因?yàn)椋硞€(gè)線程得到了對(duì)象鎖,但是另一個(gè)線程還是可以訪問沒有進(jìn)行同步的方法或者代碼。進(jìn)行了同步的方法(加鎖方法)和沒有進(jìn)行同步的方法(普通方法)是互不影響的,一個(gè)線程進(jìn)入了同步方法,得到了對(duì)象鎖,其他線程還是可以訪問那些沒有同步的方法(普通方法)。

類鎖的修飾(靜態(tài))方法和代碼塊  

public class TestSynchronized {
  public void test1() {
    synchronized (TestSynchronized.class) {
      int i = 5;
      while (i-- > 0) {
        System.out.println(Thread.currentThread().getName() + " : " + i);
        try {
          Thread.sleep(500);
        } catch (InterruptedException ie) {
        }
      }
    }
  }
 
  public static synchronized void test2() {
    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 TestSynchronized myt2 = new TestSynchronized();
    Thread test1 = new Thread(new Runnable() {
      public void run() {
        myt2.test1();
      }
    }, "test1");
    Thread test2 = new Thread(new Runnable() {
      public void run() {
        TestSynchronized.test2();
      }
    }, "test2");
    test1.start();
    test2.start();
  }
}

輸出結(jié)果如下:

test1 : 4
test1 : 3
test1 : 2
test1 : 1
test1 : 0
test2 : 4
test2 : 3
test2 : 2
test2 : 1
test2 : 0

類鎖修飾方法和代碼塊的效果和對(duì)象鎖是一樣的,因?yàn)轭愭i只是一個(gè)抽象出來(lái)的概念,只是為了區(qū)別靜態(tài)方法的特點(diǎn),因?yàn)殪o態(tài)方法是所有對(duì)象實(shí)例共用的,所以對(duì)應(yīng)著synchronized修飾的靜態(tài)方法的鎖也是唯一的,所以抽象出來(lái)個(gè)類鎖。其實(shí)這里的重點(diǎn)在下面這塊代碼,synchronized同時(shí)修飾靜態(tài)和非靜態(tài)方法

public class TestSynchronized {
  public synchronized void test1() {
    int i = 5;
    while (i-- > 0) {
      System.out.println(Thread.currentThread().getName() + " : " + i);
      try {
        Thread.sleep(500);
      } catch (InterruptedException ie) {
      }
    }
  }
 
  public static synchronized void test2() {
    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 TestSynchronized myt2 = new TestSynchronized();
    Thread test1 = new Thread(new Runnable() {
      public void run() {
        myt2.test1();
      }
    }, "test1");
    Thread test2 = new Thread(new Runnable() {
      public void run() {
        TestSynchronized.test2();
      }
    }, "test2");
    test1.start();
    test2.start();
  }
}

輸出結(jié)果如下:

test1 : 4
test2 : 4
test1 : 3
test2 : 3
test2 : 2
test1 : 2
test2 : 1
test1 : 1
test1 : 0
test2 : 0

上面代碼synchronized同時(shí)修飾靜態(tài)方法和實(shí)例方法,但是運(yùn)行結(jié)果是交替進(jìn)行的,這證明了類鎖和對(duì)象鎖是兩個(gè)不一樣的鎖,控制著不同的區(qū)域,它們是互不干擾的。同樣,線程獲得對(duì)象鎖的同時(shí),也可以獲得該類鎖,即同時(shí)獲得兩個(gè)鎖,這是允許的。

synchronized是如何保證線程安全的

如果有多個(gè)線程在同時(shí)運(yùn)行,而這些線程可能會(huì)同時(shí)運(yùn)行這段代碼。程序每次運(yùn)行結(jié)果和單線程運(yùn)行的結(jié)果是一樣的,而且其他的變量的值也和預(yù)期的是一樣的,就是線程安全的。

我們通過一個(gè)案例,演示線程的安全問題:

我們來(lái)模擬一下火車站賣票過程,總共有100張票,總共有三個(gè)窗口賣票。

public class SellTicket {
  public static void main(String[] args) {
    // 創(chuàng)建票對(duì)象
    Ticket ticket = new Ticket();
    // 創(chuàng)建3個(gè)窗口
    Thread t1 = new Thread(ticket, "窗口1");
    Thread t2 = new Thread(ticket, "窗口2");
    Thread t3 = new Thread(ticket, "窗口3");
    t1.start();
    t2.start();
    t3.start();
  }
}
 
// 模擬票
class Ticket implements Runnable {
  // 共100票
  int ticket = 100;
 
  @Override
  public void run() {
    // 模擬賣票
    while (true) {
      if (ticket > 0) {
        // 模擬選坐的操作
        try {
          Thread.sleep(1);
        } catch (InterruptedException e) {
          e.printStackTrace();
        }
        System.out.println(Thread.currentThread().getName() + "正在賣票:"
            + ticket--);
      }
    }
  }
}

運(yùn)行結(jié)果發(fā)現(xiàn):上面程序出現(xiàn)了問題

  • 票出現(xiàn)了重復(fù)的票
  • 錯(cuò)誤的票 0、-1

其實(shí),線程安全問題都是由全局變量及靜態(tài)變量引起的。若每個(gè)線程中對(duì)全局變量、靜態(tài)變量只有讀操作,而無(wú)寫操作,這個(gè)全局變量是線程安全的;若有多個(gè)線程同時(shí)執(zhí)行寫操作,一般都需要考慮線程同步,否則的話就可能影響線程安全。

那么出現(xiàn)了上述問題,我們應(yīng)該如何解決呢?

線程同步(線程安全處理Synchronized)

java中提供了線程同步機(jī)制,它能夠解決上述的線程安全問題。

線程同步的方式有兩種:

  • 方式1:同步代碼塊
  • 方式2:同步方法

同步代碼塊

同步代碼塊: 在代碼塊聲明上 加上synchronized

synchronized (鎖對(duì)象) {
  可能會(huì)產(chǎn)生線程安全問題的代碼
}

同步代碼塊中的鎖對(duì)象可以是任意的對(duì)象;但多個(gè)線程時(shí),要使用同一個(gè)鎖對(duì)象才能夠保證線程安全。

使用同步代碼塊,對(duì)火車站賣票案例中Ticket類進(jìn)行如下代碼修改:

public class SellTicket {
  public static void main(String[] args) {
    // 創(chuàng)建票對(duì)象
    Ticket ticket = new Ticket();
    // 創(chuàng)建3個(gè)窗口
    Thread t1 = new Thread(ticket, "窗口1");
    Thread t2 = new Thread(ticket, "窗口2");
    Thread t3 = new Thread(ticket, "窗口3");
    t1.start();
    t2.start();
    t3.start();
  }
}
 
// 模擬票
class Ticket implements Runnable {
  // 共100票
  int ticket = 100;
 
  Object lock = new Object();
 
  @Override
  public void run() {
    // 模擬賣票
    while (true) {
      // 同步代碼塊
      synchronized (lock) {
        if (ticket > 0) {
          // 模擬選坐的操作
          try {
            Thread.sleep(1);
          } catch (InterruptedException e) {
            e.printStackTrace();
          }
          System.out.println(Thread.currentThread().getName()
              + "正在賣票:" + ticket--);
        }
      }
    }
  }
}

當(dāng)使用了同步代碼塊后,上述的線程的安全問題,解決了。

同步方法

同步方法:在方法聲明上加上synchronized

public synchronized void method(){
    可能會(huì)產(chǎn)生線程安全問題的代碼
}

同步方法中的鎖對(duì)象是 this

使用同步方法,對(duì)火車站賣票案例中Ticket類進(jìn)行如下代碼修改:

public class SellTicket {
  public static void main(String[] args) {
    // 創(chuàng)建票對(duì)象
    Ticket ticket = new Ticket();
    // 創(chuàng)建3個(gè)窗口
    Thread t1 = new Thread(ticket, "窗口1");
    Thread t2 = new Thread(ticket, "窗口2");
    Thread t3 = new Thread(ticket, "窗口3");
    t1.start();
    t2.start();
    t3.start();
  }
}
 
// 模擬票
class Ticket implements Runnable {
  // 共100票
  int ticket = 100;
 
  Object lock = new Object();
 
  @Override
  public void run() {
    // 模擬賣票
    while (true) {
      // 同步方法
      method();
    }
  }
 
  // 同步方法,鎖對(duì)象this
  public synchronized void method() {
    if (ticket > 0) {
      // 模擬選坐的操作
      try {
        Thread.sleep(10);
      } catch (InterruptedException e) {
        e.printStackTrace();
      }
      System.out.println(Thread.currentThread().getName() + "正在賣票:"
          + ticket--);
    }
  }
}

synchronized支持鎖的重入嗎?  

我們先來(lái)看下面一段代碼:

public class ReentrantLockDemo {
  public synchronized void a() {
    System.out.println("a");
    b();
  }
 
  private synchronized void b() {
    System.out.println("b");
  }
 
  public static void main(String[] args) {
    new Thread(new Runnable() {
      @Override
      public void run() {
        ReentrantLockDemo d = new ReentrantLockDemo();
        d.a();
      }
    }).start();
  }
}

上述的代碼,我們分析一下,兩個(gè)方法,方法a和方法b都被synchronized關(guān)鍵字修飾,鎖對(duì)象是當(dāng)前對(duì)象實(shí)例,按照上文我們對(duì)synchronized的了解,如果調(diào)用方法a,在方法a還沒有執(zhí)行完之前,我們是不能執(zhí)行方法b的,方法a必須先釋放鎖,方法b才能執(zhí)行,方法b處于等待狀態(tài),那樣不就形成死鎖了嗎?那么事實(shí)真的如分析一致嗎?

運(yùn)行結(jié)果發(fā)現(xiàn):

a
b

代碼很快就執(zhí)行完了,實(shí)驗(yàn)結(jié)果與分析不一致,這就引入了另外一個(gè)概念:重入鎖。在 java 內(nèi)部,同一線程在調(diào)用自己類中其他 synchronized 方法/塊或調(diào)用父類的 synchronized 方法/塊都不會(huì)阻礙該線程的執(zhí)行。就是說(shuō)同一線程對(duì)同一個(gè)對(duì)象鎖是可重入的,而且同一個(gè)線程可以獲取同一把鎖多次,也就是可以多次重入。在JDK1.5后對(duì)synchronized關(guān)鍵字做了相關(guān)優(yōu)化。

synchronized死鎖問題

同步鎖使用的弊端:當(dāng)線程任務(wù)中出現(xiàn)了多個(gè)同步(多個(gè)鎖)時(shí),如果同步中嵌套了其他的同步。這時(shí)容易引發(fā)一種現(xiàn)象:程序出現(xiàn)無(wú)限等待,這種現(xiàn)象我們稱為死鎖。這種情況能避免就避免掉。

synchronzied(A鎖){
  synchronized(B鎖){
  }
}

我們進(jìn)行下死鎖情況的代碼演示:

public class DeadLock {
  Object obj1 = new Object();
  Object obj2 = new Object();
 
  public void a() {
    synchronized (obj1) {
      synchronized (obj2) {
        System.out.println("a");
      }
    }
  }
 
  public void b() {
    synchronized (obj2) {
      synchronized (obj1) {
        System.out.println("b");
      }
    }
  }
 
  public static void main(String[] args) {
    DeadLock d = new DeadLock();
    new Thread(new Runnable() {
      @Override
      public void run() {
        d.a();
      }
    }).start();
 
    new Thread(new Runnable() {
      @Override
      public void run() {
        d.b();
      }
    }).start();
  }
}

上述的代碼,我們分析一下,兩個(gè)方法,我們假設(shè)兩個(gè)線程T1,T2,T1運(yùn)行到方法a了,拿到了obj1這把鎖,此時(shí)T2運(yùn)行到方法b了,拿到了obj2這把鎖,T1要往下執(zhí)行,就必須等待T2釋放了obj2這把鎖,線程T2要往下面執(zhí)行,就必須等待T1釋放了持有的obj1這把鎖,他們兩個(gè)互相等待,就形成了死鎖。

為了演示的更明白,需要讓兩個(gè)方法執(zhí)行過程中睡眠10ms,要不然很難看到現(xiàn)象,因?yàn)橛?jì)算機(jī)執(zhí)行速度賊快

public class DeadLock {
  Object obj1 = new Object();
  Object obj2 = new Object();
 
  public void a() {
    synchronized (obj1) {
      try {
        Thread.sleep(10);
      } catch (InterruptedException e) {
        e.printStackTrace();
      }
      synchronized (obj2) {
        System.out.println("a");
      }
    }
  }
 
  public void b() {
    synchronized (obj2) {
      try {
        Thread.sleep(10);
      } catch (InterruptedException e) {
        e.printStackTrace();
      }
      synchronized (obj1) {
        System.out.println("b");
      }
    }
  }
 
  public static void main(String[] args) {
    DeadLock d = new DeadLock();
    new Thread(new Runnable() {
      @Override
      public void run() {
        d.a();
      }
    }).start();
 
    new Thread(new Runnable() {
      @Override
      public void run() {
        d.b();
      }
    }).start();
  }
 
}

感興趣的童鞋,下去可以試一下,程序執(zhí)行不完,永遠(yuǎn)處于等待狀態(tài)。

總結(jié)

  • sychronized是隱式鎖,是JVM底層支持的關(guān)鍵字,由JVM來(lái)維護(hù);
  • 單體應(yīng)用下,多線程并發(fā)操作時(shí),使用sychronized關(guān)鍵字可以保證線程安全;
  • sychronized可以用來(lái)修飾方法和代碼塊,此時(shí)鎖是當(dāng)前對(duì)象實(shí)例,修飾靜態(tài)方法時(shí),鎖是對(duì)象的class字節(jié)碼文件;
  • 一個(gè)線程進(jìn)入了sychronized修飾的同步方法,得到了對(duì)象鎖,其他線程還是可以訪問那些沒有同步的方法(普通方法);
  • sychronized支持鎖的重入;

以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

  • SpringBoot開發(fā)案例之打造私有云網(wǎng)盤的實(shí)現(xiàn)

    SpringBoot開發(fā)案例之打造私有云網(wǎng)盤的實(shí)現(xiàn)

    這篇文章主要介紹了SpringBoot開發(fā)案例之打造私有云網(wǎng)盤的實(shí)現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2019-04-04
  • java實(shí)現(xiàn)二分法查找出數(shù)組重復(fù)數(shù)字

    java實(shí)現(xiàn)二分法查找出數(shù)組重復(fù)數(shù)字

    這篇文章主要為大家詳細(xì)介紹了java實(shí)現(xiàn)二分法查找出數(shù)組重復(fù)數(shù)字,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2018-11-11
  • Java負(fù)載均衡算法實(shí)現(xiàn)之輪詢和加權(quán)輪詢

    Java負(fù)載均衡算法實(shí)現(xiàn)之輪詢和加權(quán)輪詢

    網(wǎng)上找了不少負(fù)載均衡算法的資源,都不夠全面,后來(lái)自己結(jié)合了網(wǎng)上的一些算法實(shí)現(xiàn),下面這篇文章主要給大家介紹了關(guān)于Java負(fù)載均衡算法實(shí)現(xiàn)之輪詢和加權(quán)輪詢的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2022-04-04
  • postman中實(shí)現(xiàn)傳遞@RequestBody參數(shù)

    postman中實(shí)現(xiàn)傳遞@RequestBody參數(shù)

    這篇文章主要介紹了postman中實(shí)現(xiàn)傳遞@RequestBody參數(shù),具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-10-10
  • java實(shí)用小技巧之判斷l(xiāng)ist是否有重復(fù)項(xiàng)簡(jiǎn)單例子

    java實(shí)用小技巧之判斷l(xiāng)ist是否有重復(fù)項(xiàng)簡(jiǎn)單例子

    這篇文章主要給大家介紹了關(guān)于java實(shí)用小技巧之判斷l(xiāng)ist是否有重復(fù)項(xiàng)的相關(guān)資料,在開發(fā)工作中我們有時(shí)需要去判斷List集合中是否含有重復(fù)的元素,需要的朋友可以參考下
    2023-10-10
  • 使用java代碼實(shí)現(xiàn)一個(gè)月內(nèi)不再提醒,通用到期的問題

    使用java代碼實(shí)現(xiàn)一個(gè)月內(nèi)不再提醒,通用到期的問題

    這篇文章主要介紹了使用java代碼實(shí)現(xiàn)一個(gè)月內(nèi)不再提醒,通用到期的問題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來(lái)看看吧
    2021-01-01
  • java GUI編程之paint繪制操作示例

    java GUI編程之paint繪制操作示例

    這篇文章主要介紹了java GUI編程之paint繪制操作,結(jié)合實(shí)例形式詳細(xì)分析了java GUI編程paint繪制相關(guān)操作技巧與使用注意事項(xiàng),需要的朋友可以參考下
    2020-01-01
  • SpringBoot 集成Kaptcha實(shí)現(xiàn)驗(yàn)證碼功能實(shí)例詳解

    SpringBoot 集成Kaptcha實(shí)現(xiàn)驗(yàn)證碼功能實(shí)例詳解

    在一個(gè)web應(yīng)用中驗(yàn)證碼是一個(gè)常見的元素。今天給大家介紹一下kaptcha的和springboot一起使用的簡(jiǎn)單例子。感興趣的朋友參考下吧
    2017-08-08
  • javaSE中數(shù)組的概念與使用詳細(xì)教程

    javaSE中數(shù)組的概念與使用詳細(xì)教程

    這篇文章主要給大家介紹了關(guān)于javaSE中數(shù)組的概念與使用的相關(guān)資料,數(shù)組在內(nèi)存中是一段連續(xù)的空間,空間的編號(hào)都是從0開始的,依次遞增,該編號(hào)稱為數(shù)組的下標(biāo),需要的朋友可以參考下
    2023-08-08
  • Java SpringBoot模板引擎之 Thymeleaf入門詳解

    Java SpringBoot模板引擎之 Thymeleaf入門詳解

    jsp有著強(qiáng)大的功能,能查出一些數(shù)據(jù)轉(zhuǎn)發(fā)到JSP頁(yè)面以后,我們可以用jsp輕松實(shí)現(xiàn)數(shù)據(jù)的顯示及交互等,包括能寫Java代碼。但是,SpringBoot首先是以jar的方式,不是war;其次我們的tomcat是嵌入式的,所以現(xiàn)在默認(rèn)不支持jsp
    2021-10-10

最新評(píng)論

蓬溪县| 永安市| 吴桥县| 天门市| 平山县| 息烽县| 汤阴县| 宿松县| 莱芜市| 永州市| 会宁县| 白河县| 章丘市| 廊坊市| 南宫市| 广东省| 吕梁市| 普兰县| 都匀市| 绥滨县| 县级市| 乐昌市| 喜德县| 龙海市| 谷城县| 隆昌县| 个旧市| 银川市| 曲阳县| 乐清市| 武宁县| 哈密市| 浦城县| 曲松县| 武冈市| 右玉县| 寿阳县| 梧州市| 共和县| 大丰市| 伽师县|