日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

JAVA多线程提高十四: 面试题

發布時間:2025/3/21 编程问答 15 豆豆
生活随笔 收集整理的這篇文章主要介紹了 JAVA多线程提高十四: 面试题 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

前面針對多線程相關知識點進行了學習,那么我們來來看看常見的面試題:

1. 空中網面試題1 package com.kongzhongwang.interview; import java.util.concurrent.ArrayBlockingQueue; import java.util.concurrent.BlockingQueue; //myeclipse強大功能:將代碼直接復制到項目的src路徑下可以自動相應生成包名和類名 /** * * 空中網面試題1:現有程序代碼模擬產生16個日志對象,并且需要運行16秒才能打印完這些日志,請在程序中增加四個線程去調用 * parseLog()方法來分頭打印這16個日志對象,程序只需運行4秒即可打印完這些日志對象。 * 考察新技術BlockingQueue */ public class ReadLog { public static void main(String[] args) { /*此處有一個巧合:這里ArrayBlockingQueue<String>(1)和ArrayBlockingQueue<String>(16) * 達到的效果一樣,并且前者產生的數據組合更整齊;目前推測是巧合,希望大牛發現因果了告知一聲 */ final BlockingQueue<String> queue = new ArrayBlockingQueue<String>(1); for (int i = 0; i < 4; i++) { new Thread(new Runnable() { public void run() { while (true) { try { String log = queue.take(); parseLog(log); } catch (InterruptedException e) { e.printStackTrace(); } } } }).start(); } System.out.println("begin:" + (System.currentTimeMillis() / 1000)); /* * 模擬處理16個日志,下面代碼產生了16個日志對象;當前代碼需要運行16秒才能打印完成這些日志對象; * 修改程序代碼,開四個線程讓16個對象在4秒內打完 */ for (int i = 0; i < 16; i++) { // 這行代碼不能改動 final String log = "" + (i + 1); // 這行代碼不能改動 { // ReadLog.parseLog(log); try { queue.put(log); } catch (InterruptedException e) { e.printStackTrace(); } } } } // parseLog內部代碼不能動 public static void parseLog(String log) { System.out.println(log + ":" + System.currentTimeMillis() / 1000); try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } } } 2. 空中網面試題2 package com.kongzhongwang.interview; import java.util.concurrent.Semaphore; import java.util.concurrent.SynchronousQueue; /** * 空中網面試題2: 現成程序中的Test類中的代碼在不斷地產生數據,然后交給TestDo.doSome()方法去處理; * 這就好像是生產者在不斷地產生數據,消費者在不斷地消費數據。請將程序改造成有10個線程來消費生產者產生的數據, * 這些消費者都調用TestDo.doSome()方法去處理,固每個消費者都需要1秒才能處理完,程序應該保證這些 * 消費者線程依次有序的消費數據,只有上一個消費者消費完后,下一個消費者才能消費數據,下一個消費者是誰都可以, 但要保證消費者拿到的數據是有順序的。 */ public class Test { public static void main(String[] args) { //使用semaphore信號燈相當于上一個lock鎖 final Semaphore semaphore = new Semaphore(1); //新的隊列方式 final SynchronousQueue<String> queue = new SynchronousQueue<String>(); for(int i=0;i<10;i++){ new Thread(new Runnable() { @Override public void run() { try { semaphore.acquire(); String input = queue.take(); String output = TestDo.doSome(input); System.out.println(Thread.currentThread().getName() + ":" + output); semaphore.release(); } catch (InterruptedException e) { e.printStackTrace(); } } }).start(); } System.out.println("begin:" + (System.currentTimeMillis() / 1000)); for (int i = 0; i < 10; i++) { // 這行代碼不能改動 String input = i + ""; // 這行代碼不能改動 try { queue.put(input); } catch (InterruptedException e) { e.printStackTrace(); } } } } // TestDo類不能動 class TestDo { public static String doSome(String input) { try { Thread.sleep(1000); } catch (Exception e) { e.printStackTrace(); } String output = input + ":" + (System.currentTimeMillis() / 1000); return output; } } 3.空中網面試題3 package com.kongzhongwang.interview; import java.util.ArrayList; import java.util.Iterator; import java.util.concurrent.CopyOnWriteArrayList; public class Tests extends Thread { /** * 空中網面試題3: 現有程序同時啟動了四個線程去調用TestDo.doSome(key,value)方法; * 由于TestsDo.doSome(key,value)方法內的代碼是先暫停1秒,然后再輸出以秒為單位的當前時間值, * 所以會打印出四個相同的時間值,如下所示:4:4 1258199615 1:1 1258199615 3:3 1258199615 2:2 * 1258199615 ;請修改代碼,如果有幾個線程調用TestDo.doSome(key,value)方法時; * 傳遞進去的key值相等(equals比較為true),則這幾個線程應互斥輸出結果,即當有兩個線程的key都為1時, * 它們中的一個要比其他線程晚一步輸出結果,如下所示:4:4 1258199615 1:1 1258199615 3:3 1258199615 1:2 * 1258199616 ;總之每個線程中指定的key相等時;這些相等的線程應每隔1秒輸出時間值(要用互斥), * key不同,則并行執行(相互之間不互斥) */ private TestsDo testDo; private String key; private String value; private Tests(String key, String key2, String value) { this.testDo = TestsDo.getInstance(); /* * 常量“1”和“1”是同一個對象,下面這行代碼就是要用“1”+“”的方式產生新的對象; * 以實現內容沒有改變,仍然相等(都還為“1”),但對象卻不再是同一個的效果 */ this.key = key + key2; /* * a = "1"+""; * b = "2"+""; * a和b是同一個對象,因為編譯器在執行之前就會將其優化為 a=“1”; * 但是this.key = key + key2;這句,編譯器不會給你優化, * 因為你是屬性變量,編譯器不知道你將來要傳入什么值 */ this.value = value; } public static void main(String[] args) { Tests a = new Tests("1", "", "1"); Tests b = new Tests("1", "", "2"); Tests c = new Tests("3", "", "3"); Tests d = new Tests("4", "", "4"); System.out.println("begin:" + (System.currentTimeMillis() / 1000)); a.start(); b.start(); c.start(); d.start(); } public void run() { testDo.doSome(key, value); } } class TestsDo { private TestsDo() {} private static TestsDo _instance = new TestsDo(); public static TestsDo getInstance() { return _instance; } //傳統寫法,沒有考慮到線程并發問題 // private ArrayList keys = new ArrayList(); private CopyOnWriteArrayList keys = new CopyOnWriteArrayList(); public void doSome(Object key,String value){ Object o = key; if(! keys.contains(o)){ keys.add(o); }else{ //迭代的過程中不能進行其他操作; for(Iterator iter = keys.iterator();iter.hasNext();){ /*這里的休眠作用:為了讓大家看到,使用傳統的private ArrayList keys = new ArrayList(); * 會導致Exception in thread "Thread-1" java.util.ConcurrentModificationException異常 * 因為迭代的過程中不能進行其他操作;你非要在迭代的時候向其中添加數據就會導致這種異常,而且在迭代中放入休眠這種錯誤百發百中。 */ try { Thread.sleep(20); } catch (InterruptedException e) { e.printStackTrace(); } Object oo = iter.next(); if(o.equals(oo)){ o = oo; } } } //這里為了區別是不同對象,所以不能直接使用synchronized(key) synchronized(o) //大括號內的是需要同步的代碼,不能改動 { try{ Thread.sleep(1000); System.out.println(key+":"+value+":" + (System.currentTimeMillis() / 1000)); }catch(Exception e){ e.printStackTrace(); } } } }

?

其它面試題:

https://www.cnblogs.com/Jansens520/p/8624708.html

Java多線程常用面試題(含答案,精心總結整理)

?

轉載于:https://www.cnblogs.com/pony1223/p/9327152.html

總結

以上是生活随笔為你收集整理的JAVA多线程提高十四: 面试题的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。