激情欧美日韩一区二区,浪货撅高贱屁股求主人调教视频,精品无码成人片一区二区98,国产高清av在线播放,色翁荡息又大又硬又粗视频

Java程序員面試中的多線(xiàn)程問(wèn)題

時(shí)間:2023-04-02 09:06:29 面試問(wèn)題 我要投稿
  • 相關(guān)推薦

Java程序員面試中的多線(xiàn)程問(wèn)題

  0、Java中多線(xiàn)程同步是什么?

Java程序員面試中的多線(xiàn)程問(wèn)題

  在多線(xiàn)程程序下,同步能控制對共享資源的訪(fǎng)問(wèn)。如果沒(méi)有同步,當一個(gè)Java線(xiàn)程在修改一個(gè)共享變量時(shí),另外一個(gè)線(xiàn)程正在使用或者更新同一個(gè)變量,這樣容易導致程序出現錯誤的結果。

  1、解釋實(shí)現多線(xiàn)程的幾種方法?

  一Java線(xiàn)程可以實(shí)現Runnable接口或者繼承Thread類(lèi)來(lái)實(shí)現,當你打算多重繼承時(shí),優(yōu)先選擇實(shí)現Runnable。

  2、Thread.start()與Thread.run()有什么區別?

  Thread.start()方法(native)啟動(dòng)線(xiàn)程,使之進(jìn)入就緒狀態(tài),當cpu分配時(shí)間該線(xiàn)程時(shí),由JVM調度執行run()方法。

  3、為什么需要run()和start()方法,我們可以只用run()方法來(lái)完成任務(wù)嗎?

  我們需要run()&start()這兩個(gè)方法是因為JVM創(chuàng )建一個(gè)單獨的線(xiàn)程不同于普通方法的調用,所以這項工作由線(xiàn)程的start方法來(lái)完成,start由本地方法實(shí)現,需要顯示地被調用,使用這倆個(gè)方法的另外一個(gè)好處是任何一個(gè)對象都可以作為線(xiàn)程運行,只要實(shí)現了Runnable接口,這就避免因繼承了Thread類(lèi)而造成的Java的多繼承問(wèn)題。

  4、什么是ThreadLocal類(lèi),怎么使用它?

  ThreadLocal是一個(gè)線(xiàn)程級別的局部變量,并非“本地線(xiàn)程”。ThreadLocal為每個(gè)使用該變量的線(xiàn)程提供了一個(gè)獨立的變量副本,每個(gè)線(xiàn)程修改副本時(shí)不影響其它線(xiàn)程對象的副本(譯者注)。

  下面是線(xiàn)程局部變量(ThreadLocal variables)的關(guān)鍵點(diǎn):

  一個(gè)線(xiàn)程局部變量(ThreadLocal variables)為每個(gè)線(xiàn)程方便地提供了一個(gè)單獨的變量。

  ThreadLocal實(shí)例通常作為靜態(tài)的私有的(private static)字段出現在一個(gè)類(lèi)中,這個(gè)類(lèi)用來(lái)關(guān)聯(lián)一個(gè)線(xiàn)程。

  當多個(gè)線(xiàn)程訪(fǎng)問(wèn)ThreadLocal實(shí)例時(shí),每個(gè)線(xiàn)程維護ThreadLocal提供的獨立的變量副本。

  常用的使用可在DAO模式中見(jiàn)到,當DAO類(lèi)作為一個(gè)單例類(lèi)時(shí),數據庫鏈接(connection)被每一個(gè)線(xiàn)程獨立的維護,互不影響。(基于線(xiàn)程的單例)

  5、什么時(shí)候拋出InvalidMonitorStateException異常,為什么?

  調用wait()/notify()/notifyAll()中的任何一個(gè)方法時(shí),如果當前線(xiàn)程沒(méi)有獲得該對象的鎖,那么就會(huì )拋出IllegalMonitorStateException的異常(也就是說(shuō)程序在沒(méi)有執行對象的任何同步塊或者同步方法時(shí),仍然嘗試調用wait()/notify()/notifyAll()時(shí))。由于該異常是RuntimeExcpetion的子類(lèi),所以該異常不一定要捕獲(盡管你可以捕獲只要你愿意).作為RuntimeException,此類(lèi)異常不會(huì )在wait(),notify(),notifyAll()的方法簽名提及。

  6、Sleep()、suspend()和wait()之間有什么區別?

  Thread.sleep()使當前線(xiàn)程在指定的時(shí)間處于“非運行”(Not Runnable)狀態(tài)。線(xiàn)程一直持有對象的監視器。比如一個(gè)線(xiàn)程當前在一個(gè)同步塊或同步方法中,其它線(xiàn)程不能進(jìn)入該塊或方法中。如果另一線(xiàn)程調用了 interrupt()方法,它將喚醒那個(gè)“睡眠的”線(xiàn)程。

  注意:sleep()是一個(gè)靜態(tài)方法。這意味著(zhù)只對當前線(xiàn)程有效,一個(gè)常見(jiàn)的錯誤是調用t.sleep(),(這里的t是一個(gè)不同于當前線(xiàn)程的線(xiàn)程)。即便是執行t.sleep(),也是當前線(xiàn)程進(jìn)入睡眠,而不是t線(xiàn)程。t.suspend()是過(guò)時(shí)的方法,使用suspend()導致線(xiàn)程進(jìn)入停滯狀態(tài),該線(xiàn)程會(huì )一直持有對象的監視器,suspend()容易引起死鎖問(wèn)題。

  object.wait()使當前線(xiàn)程出于“不可運行”狀態(tài),和sleep()不同的是wait是object的方法而不是thread。調用 object.wait()時(shí),線(xiàn)程先要獲取這個(gè)對象的對象鎖,當前線(xiàn)程必須在鎖對象保持同步,把當前線(xiàn)程添加到等待隊列中,隨后另一線(xiàn)程可以同步同一個(gè)對象鎖來(lái)調用object.notify(),這樣將喚醒原來(lái)等待中的線(xiàn)程,然后釋放該鎖;旧蟱ait()/notify()與sleep() /interrupt()類(lèi)似,只是前者需要獲取對象鎖。

  7、在靜態(tài)方法上使用同步時(shí)會(huì )發(fā)生什么事?

  同步靜態(tài)方法時(shí)會(huì )獲取該類(lèi)的“Class”對象,所以當一個(gè)線(xiàn)程進(jìn)入同步的靜態(tài)方法中時(shí),線(xiàn)程監視器獲取類(lèi)本身的對象鎖,其它線(xiàn)程不能進(jìn)入這個(gè)類(lèi)的任何靜態(tài)同步方法。它不像實(shí)例方法,因為多個(gè)線(xiàn)程可以同時(shí)訪(fǎng)問(wèn)不同實(shí)例同步實(shí)例方法。

  8、當一個(gè)同步方法已經(jīng)執行,線(xiàn)程能夠調用對象上的非同步實(shí)例方法嗎?

  可以,一個(gè)非同步方法總是可以被調用而不會(huì )有任何問(wèn)題。實(shí)際上,Java沒(méi)有為非同步方法做任何檢查,鎖對象僅僅在同步方法或者同步代碼塊中檢查。如果一個(gè)方法沒(méi)有聲明為同步,即使你在使用共享數據Java照樣會(huì )調用,而不會(huì )做檢查是否安全,所以在這種情況下要特別小心。一個(gè)方法是否聲明為同步取決于臨界區訪(fǎng)問(wèn)(critial section access),如果方法不訪(fǎng)問(wèn)臨界區(共享資源或者數據結構)就沒(méi)必要聲明為同步的。

  下面有一個(gè)示例說(shuō)明:Common類(lèi)有兩個(gè)方法synchronizedMethod1()和method1(),MyThread類(lèi)在獨立的線(xiàn)程中調用這兩個(gè)方法。

  public class Common {

  public synchronized void synchronizedMethod1() {

  System.out.println("synchronizedMethod1 called");

  try {

  Thread.sleep(1000);

  } catch (InterruptedException e) {

  e.printStackTrace();

  }

  System.out.println("synchronizedMethod1 done");

  }

  public void method1() {

  System.out.println("Method 1 called");

  try {

  Thread.sleep(1000);

  } catch (InterruptedException e) {

  e.printStackTrace();

  }

  System.out.println("Method 1 done");

  }

  }

  public class MyThread extends Thread {

  private int id = 0;

  private Common common;

  public MyThread(String name, int no, Common object) {

  super(name);

  common = object;

  id = no;

  }

  public void run() {

  System.out.println("Running Thread" + this.getName());

  try {

  if (id == 0) {

  common.synchronizedMethod1();

  } else {

  common.method1();

  }

  } catch (Exception e) {

  e.printStackTrace();

  }

  }

  public static void main(String[] args) {

  Common c = new Common();

  MyThread t1 = new MyThread("MyThread-1", 0, c);

  MyThread t2 = new MyThread("MyThread-2", 1, c);

  t1.start();

  t2.start();

  }

  }

  這里是程序的輸出:

  Running ThreadMyThread-1

  synchronizedMethod1 called

  Running ThreadMyThread-2

  Method 1 called

  synchronizedMethod1 done

  Method 1 done

  結果表明即使synchronizedMethod1()方法執行了,method1()也會(huì )被調用。

  9、 在一個(gè)對象上兩個(gè)線(xiàn)程可以調用兩個(gè)不同的同步實(shí)例方法嗎?

  不能,因為一個(gè)對象已經(jīng)同步了實(shí)例方法,線(xiàn)程獲取了對象的對象鎖。所以只有執行完該方法釋放對象鎖后才能執行其它同步方法?聪旅娲a示例非常清晰:Common 類(lèi) 有synchronizedMethod1()和synchronizedMethod2()方法,MyThread調用這兩個(gè)方法。

  public class Common {

  public synchronized void synchronizedMethod1() {

  System.out.println("synchronizedMethod1 called");

  try {

  Thread.sleep(1000);

  } catch (InterruptedException e) {

  e.printStackTrace();

  }

  System.out.println("synchronizedMethod1 done");

  }

  public synchronized void synchronizedMethod2() {

  System.out.println("synchronizedMethod2 called");

  try {

  Thread.sleep(1000);

  } catch (InterruptedException e) {

  e.printStackTrace();

  }

  System.out.println("synchronizedMethod2 done");

  }

  }

  public class MyThread extends Thread {

  private int id = 0;

  private Common common;

  public MyThread(String name, int no, Common object) {

  super(name);

  common = object;

  id = no;

  }

  public void run() {

  System.out.println("Running Thread" + this.getName());

  try {

  if (id == 0) {

  common.synchronizedMethod1();

  } else {

  common.synchronizedMethod2();

  }

  } catch (Exception e) {

  e.printStackTrace();

  }

  }

  public static void main(String[] args) {

  Common c = new Common();

  MyThread t1 = new MyThread("MyThread-1", 0, c);

  MyThread t2 = new MyThread("MyThread-2", 1, c);

  t1.start();

  t2.start();

  }

  }

  10、 什么是死鎖

  死鎖就是兩個(gè)或兩個(gè)以上的線(xiàn)程被無(wú)限的阻塞,線(xiàn)程之間相互等待所需資源。這種情況可能發(fā)生在當兩個(gè)線(xiàn)程嘗試獲取其它資源的鎖,而每個(gè)線(xiàn)程又陷入無(wú)限等待其它資源鎖的釋放,除非一個(gè)用戶(hù)進(jìn)程被終止。就JavaAPI而言,線(xiàn)程死鎖可能發(fā)生在一下情況。

  ●當兩個(gè)線(xiàn)程相互調用Thread.join()

  ●當兩個(gè)線(xiàn)程使用嵌套的同步塊,一個(gè)線(xiàn)程占用了另外一個(gè)線(xiàn)程必需的鎖,互相等待時(shí)被阻塞就有可能出現死鎖。

  11、什么是線(xiàn)程餓死,什么是活鎖?

  線(xiàn)程餓死和活鎖雖然不想是死鎖一樣的常見(jiàn)問(wèn)題,但是對于并發(fā)編程的設計者來(lái)說(shuō)就像一次邂逅一樣。

  當所有線(xiàn)程阻塞,或者由于需要的資源無(wú)效而不能處理,不存在非阻塞線(xiàn)程使資源可用。JavaAPI中線(xiàn)程活鎖可能發(fā)生在以下情形:

  ●當所有線(xiàn)程在程序中執行Object.wait(0),參數為0的wait方法。程序將發(fā)生活鎖直到在相應的對象上有線(xiàn)程調用Object.notify()或者Object.notifyAll()。

  ●當所有線(xiàn)程卡在無(wú)限循環(huán)中。

【Java程序員面試中的多線(xiàn)程問(wèn)題】相關(guān)文章:

2016年java多線(xiàn)程面試題及答案03-31

Java程序員面試寶典12-14

java程序員面試指南11-26

java程序員面試試題11-30

java程序員面試題08-15

初級java程序員面試要求01-22

java招聘面試常見(jiàn)問(wèn)題12-10

java面試最常見(jiàn)問(wèn)題03-24

java程序員面試自我介紹04-09

請問(wèn)面試中的問(wèn)題!11-20

激情欧美日韩一区二区,浪货撅高贱屁股求主人调教视频,精品无码成人片一区二区98,国产高清av在线播放,色翁荡息又大又硬又粗视频