Java多線程面試題歸納,java多線程試題

來源:互聯網
上載者:User

Java多線程面試題歸納,java多線程試題
1、多線程有哪幾種實現方法?舉個例子說明下線程的同步。

(1)Java多線程有兩種實現方式:繼承Thread類和實現Runnable介面,Thread就是實現了Runnable介面。

兩個最簡單的線程例子:

package chc.runnable;public class ThreadTest2 {    public static void main(String[] args) throws InterruptedException {        Thread1 t = new Thread1();        //t.run(); //這裡也不能直接調用方法        t.start();        for (int i = 0; i < 100; i++) {            System.out.println("main:"+i);        }    }}class Thread1 extends Thread{    public void run() {        for (int i = 0; i < 100; i++) {            System.out.println("Thread-----:"+i);        }    }}
package chc.runnable;public class ThreadTest1 {public static void main(String[] args) {Runnable1 r =new Runnable1();Thread t1=new Thread(r);t1.start();}}class Runnable1  implements Runnable {public void run() {// TODO Auto-generated method stubfor (int i = 1; i <= 5; i++) {System.out.println("實現Runnable介面的線程----->"+i);}}}

通過上兩個例子發現,當啟動線程的時候並不影響主程式的繼續執行。

(2)線程同步問題

使用synchronnized關鍵字

銀行賬戶存取錢的問題:

public class ThreadTest {public static void main(String[] args){ThreadA  t1=new ThreadA();t1.start();ThreadB  t2=new ThreadB();t2.start();}}class ThreadA extends Thread{@Overridepublic void run(){for(int i=0;i<100;i++){account.add();try {sleep(10);//類比銀行系統處理時間} catch (InterruptedException e) {// TODO Auto-generated catch blocke.printStackTrace();}}}}class ThreadB extends Thread{@Overridepublic void run() {for(int i=0;i<100;i++){account.remove();try {sleep(10);<span style="font-family: SimSun;">//類比銀行系統處理時間</span>} catch (InterruptedException e) {// TODO Auto-generated catch blocke.printStackTrace();}}}}class account {public static   int count=1000;//減去100元public static synchronized void remove(){count=count-100;System.out.println("減去100元,卡內餘額"+count);}//增加100元public static synchronized void add(){count=count+100;System.out.println("加上100元,卡內餘額"+count);}}
注意:上例中將account類的add()和remove()方法都加上了static關鍵字,因為這樣線上程中可以直接通過類名調用到這兩個方法,而不需要執行個體化對象。

因為synchronized同步只對同一個對象中的方法有效,也就是說一個線程正在執行account的add()方法,另一個線程是可以調用到另一個對象的add方法的。

2、啟動一個線程是用run()還是start(),調用的時候有什麼區別?

當然是start()了,當調用線程的start()方法的時候,線程就會進入到就緒狀態

run()方法是線程的執行入口,當線程從就緒狀態進入到執行狀態時首先要從run()方法開始執行。

當然,我們也是可以直接通過線程對象調用該對象的run()方法的,只是這隻是一次普通的調用,並沒有啟動任何一個線程。

當我們調用start()方法時,是另外啟動了一個線程去執行線程類的代碼,並不影響主程式的執行,但是調用run()方法的時候要等待run()方法內的代碼執

行完主程式才可以向下執行,舉個例子:

public class ThreadDemo2 {public static void main(String[] args) {Thread5 t1=new Thread5();Thread6 t2=new Thread6();t1.run();t2.start();for(int i=0;i<100;i++){System.out.println("主進程執行:"+i);}}}class Thread5 extends Thread{@Overridepublic void run() {for(int i=0;i<100;i++){System.out.println("Thread5執行:"+i);}}}class Thread6 extends Thread{@Overridepublic void run() {for(int i=0;i<100;i++){System.out.println("Thread6執行:"+i);}}}
輸出結果的順序是:Thread5全部列印完後 Thread6和主程式交替列印。驗證了上面的說法

3、當一個線程進入到一個對象的synchronized方法,那麼其他線程是否可以進入該對象的其它方法?

不一定,看情況

如果其它方法加了static關鍵字,那麼該方法屬於類,不屬於對象,不能與對象的方法保持同步(即使有synchronized關鍵字),是能進入的。

如果其它方法不帶有static關鍵字且帶有synchronized關鍵字,那麼不能進入,如果不帶,則能。

再其次就看方法內部有沒有wait()方法釋放鎖了

4、子線程迴圈2次,接著主線程迴圈3次,接著子線程迴圈3次,接著主線程迴圈3次,如此迴圈5次,請寫出程式碼。

public class ThreadDemo5 {static boolean thread_flag=false;//指示子線程迴圈是否結束static boolean main_flag=true;   //調用子線程的start方法後變為true,迴圈等待thread_flag為true(也就是子線程迴圈完)的時刻,主線程迴圈完又變為false;public static void main(String[] args) {for(int k=0;k<5;k++){Thread7 t=new Thread7();t.start();main_flag=true;while (main_flag) {//迴圈等待thread_fif(thread_flag){for(int i=0;i<3;i++){System.out.println("主線程第一次迴圈"+(i+1)+"次");}thread_flag=false;main_flag=false;}}}}}class Thread7 extends Thread {static boolean flag=true;//標誌子線程第幾次迴圈,當值為true的時候子線程迴圈2次,否則迴圈3次public void run() {if(flag){for(int i=0;i<2;i++){System.out.println("子線程第一次迴圈"+(i+1)+"次");}flag=false;}else{for(int i=0;i<3;i++){System.out.println("子線程第二次迴圈"+(i+1)+"次");}flag=true;}ThreadDemo5.thread_flag=true;}}

這個題就是要注意調用子線程的start方法的時候並不能阻止主程式繼續向下執行,所以我們要用變數來標記。

5、sleep()和wait()有何異同?

(1)首先一個最明顯的區別是  wait是Object類的方法,而sleep()是Thread類的靜態方法,誰調用了該方法誰去休眠,即使在a線程裡調用了b線程的sleep方法,實際上還是a線程去休眠.

(2)比較重要的一點是sleep沒有釋放出鎖,而wait釋放了鎖,是其他線程可以使用同步塊資源。

     sleep不出讓系統資源;wait是進入線程等待池等待,出讓系統資源,其他線程可以佔用CPU。一般wait不會加時間限制,因為如果wait線程的運行資源不夠,再出來也沒用,要

     等待其他線程調用notify/notifyAll喚醒等待池中的所有線程,才會進入就緒隊列等待OS分配系統資源。sleep(milliseconds)可以用時間指定使它自動喚醒過來,如果時間不到

     只能調用interrupt()強行打斷。

(3)使用範圍:

     wait,notify和notifyAll只能在同步控制方法或者同步控制塊裡面使用,而sleep可以在任何地方使用 
     synchronized(x){ 
       x.notify() 
       //或者wait() 
      }

(4)sleep需要捕獲異常,而wait不需要。

6、現在有T1 T2 T3三個線程,怎樣保證T2在T1執行完之後執行 T3在T2執行完之後執行

這題主要是考察對join()方法的使用。

當線程A當中執行了線程B.join(),那麼A線程要等待B線程執行完才可以執行。

public class JoinDemo {public static void main(String[] args) {T1 t1=new T1("T1");T2 t2=new T2("T2");T3 t3=new T3("T3");t1.start();try {t1.join();} catch (InterruptedException e) {// TODO Auto-generated catch blocke.printStackTrace();}t2.start();try {t2.join();} catch (InterruptedException e) {// TODO Auto-generated catch blocke.printStackTrace();}t3.start();}}class T1 extends  Thread{private String name;public T1(String name) {this.name=name;}@Overridepublic void run() {for(int i=0;i<5;i++){try {sleep(5);} catch (InterruptedException e) {// TODO Auto-generated catch blocke.printStackTrace();}System.out.println(this.name+"迴圈"+i);}}}class T2 extends  Thread{private String name;public T2(String name) {this.name=name;}@Overridepublic void run() {for(int i=0;i<5;i++){try {sleep(5);} catch (InterruptedException e) {// TODO Auto-generated catch blocke.printStackTrace();}System.out.println(this.name+"迴圈"+i);}}}class T3 extends  Thread{private String name;public T3(String name) {this.name=name;}@Overridepublic void run() {for(int i=0;i<5;i++){System.out.println(this.name+"迴圈"+i);}}}

7、簡述synchronized和java.util.concurrent.locks.Lock的異同?

主要相同點:Lock能完成synchronized所實現的所有功能

主要不同點:Lock有比synchronized更精確的線程語義和更好的效能。synchronized會自動釋放鎖,而Lock一定要求程式員手工釋放,並且必須在finally從句中釋放。

Lock還有更強大的功能,例如,它的tryLock方法可以非阻塞方式去拿鎖。

8、死結問題

後續補充……


java 線程面試題

我不知道你是不是這個意思,thread1,thread2兩個線程每次讓j增加1,thread3,thread4兩個線程每次讓j減少1,四個線程每個都調用250次相關加減一操作。最終j的結果都是100.
下面程式,總計會列印出1000個數,不管怎麼樣最後一個數永遠是100,即j的終值永遠是100,為了看中間結果運行過程我加了sleep,但無關緊要。你看看符合你要求不?
就像樓上說的,啟動1000條線程不是很明白,不一致的繼續討論
package com.kalort;

public class ThreadTest
{
public static void main(String[] args)
{
Operator operator = new Operator();
Thread thread1 = new IncreaseThread(operator);
Thread thread2 = new IncreaseThread(operator);
Thread thread3 = new DecreaseThread(operator);
Thread thread4 = new DecreaseThread(operator);
thread1.start();
thread2.start();
thread3.start();
thread4.start();
}
}

class IncreaseThread extends Thread
{
private Operator operator;

public IncreaseThread(Operator operator)
{
this.operator = operator;
}

public void run()
{
for (int i = 0; i < 250; i++)
{
try
{
Thread.sleep((long)(Math.random() * 100));
}
catch (InterruptedException e)
{
e.printStackTrace();
}
operator.increase();
}
}
}

class DecreaseThread extends Thread
{
private Operator operator;

public DecreaseThread(Operator operator)
{
this.operator = operator;
}

public void run()
{
for (int i = 0; i < 250; i++)
{
try
{
Thread.sleep((long)(Math.random() * 100));
}
catch (InterruptedException e)
{
e.printStackTrace();
}
operator.decrease();
}
}
}

class Operator
{
private int j = 100;

public synchronized void increase()
{
while (100 != j)
{
try
{
wait(); /&#......餘下全文>>
 
java面試題:用多線程顯示,每三個數字為一組,直到30

public class Test{public static Object obj = new Object();public static void main(String[] args){new A().start();new B().start();}}class A extends Thread{public void run(){try{synchronized(Test.obj){for(int i = 1 ; i < 31;i += 6){Test.obj.notify();System.out.println("線程A:"+ i);System.out.println("線程A:"+ (i+1));System.out.println("線程A:"+ (i+2));Test.obj.wait();}}}catch(Exception e){e.printStackTrace();}}}class B extends Thread{public void run(){try{synchronized(Test.obj){for(int i = 4 ; i < 31;i += 6){Test.obj.notify();System.out.println("線程B:"+ i);System.out.println("線程B:"+ (i+1));System.out.println("線程B:"+ (i+2));Test.obj.wait();}}}catch(Exception e){e.printStackTrace();}}}
 

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.