㈠ java線程組,線程池,線程隊列分別是什麼有什麼區別
你好,我可以給你詳細解釋一下:
線程組表示一個線程的集合。此外,線程組也可以包含其他線程組。線程組構成一棵樹,在樹中,除了初始線程組外,每個線程組都有一個父線程組。
允許線程訪問有關自己的線程組的信息,但是不允許它訪問有關其線程組的父線程組或其他任何線程組的信息。
線程池:我們可以把並發執行的任務傳遞給一個線程池,來替代為每個並發執行的任務都啟動一個新的線程。只要池裡有空閑的線程,任務就會分配給一個線程執行。在線程池的內部,任務被插入一個阻塞隊列(Blocking Queue ),線程池裡的線程會去取這個隊列里的任務。當一個新任務插入隊列時,一個空閑線程就會成功的從隊列中取出任務並且執行它。
線程池經常應用在多線程伺服器上。每個通過網路到達伺服器的連接都被包裝成一個任務並且傳遞給線程池。線程池的線程會並發的處理連接上的請求。以後會再深入有關 Java 實現多線程伺服器的細節。
線程隊列:是指線程處於擁塞的時候形成的調度隊列
排隊有三種通用策略:
直接提交。工作隊列的默認選項是 SynchronousQueue,它將任務直接提交給線程而不保持它們。在此,如果不存在可用於立即運行任務的線程,則試圖把任務加入隊列將失敗,因此會構造一個新的線程。此策略可以避免在處理可能具有內部依賴性的請求集時出現鎖。直接提交通常要求無界 maximumPoolSizes 以避免拒絕新提交的任務。當命令以超過隊列所能處理的平均數連續到達時,此策略允許無界線程具有增長的可能性。
無界隊列。使用無界隊列(例如,不具有預定義容量的 LinkedBlockingQueue)將導致在所有corePoolSize 線程都忙時新任務在隊列中等待。這樣,創建的線程就不會超過 corePoolSize。(因此,maximumPoolSize的值也就無效了。)當每個任務完全獨立於其他任務,即任務執行互不影響時,適合於使用無界隊列;例如,在 Web頁伺服器中。這種排隊可用於處理瞬態突發請求,當命令以超過隊列所能處理的平均數連續到達時,此策略允許無界線程具有增長的可能性。
有界隊列。當使用有限的 maximumPoolSizes時,有界隊列(如 ArrayBlockingQueue)有助於防止資源耗盡,但是可能較難調整和控制。隊列大小和最大池大小可能需要相互折衷:使用大型隊列和小型池可以最大限度地降低 CPU 使用率、操作系統資源和上下文切換開銷,但是可能導致人工降低吞吐量。如果任務頻繁阻塞(例如,如果它們是 I/O邊界),則系統可能為超過您許可的更多線程安排時間。使用小型隊列通常要求較大的池大小,CPU使用率較高,但是可能遇到不可接受的調度開銷,這樣也會降低吞吐量。
㈡ Java如何解決超賣
一、人數閥門設計:進行用戶人群過濾。
商品數量只有100份,秒殺人數有10000人,那麼我們就設計1道閥門(根據情況,可以設計3道或者2道都可以的)。
在整點的時候,我們對點擊了「購買」按鈕後,我們只運行500人進入信息填寫頁面,信息填寫完成後提交訂單。效果如下:
①商品詳情點擊購買(秒殺)--》②輸入信息提交訂單--》③進行支付
10000人 500人 (這里也可以設計閥門,只允許多少人進入支付)
其他未進入的如何處理乃?顯示已搶完或者排隊等待(這就是後面要提到的排隊系統設計)。
二、會員排隊設計:對用戶進行排隊,排在前面的先購買
這相當於是消息隊列模式了,如果秒殺是立即知道結果,排隊可能會有點雞肋。
在第二步②輸入信息提交訂單後進行排隊,排在前面的先購買,排在後面的後購買
三、問答問題設計:過濾掉一些反應慢的用戶
在第一步①點擊購買後跳轉到問題頁面,用戶必須回答正確問題後,方可進入後面的流程
四、庫存緩存設計:緩存庫存,判斷用戶購買的商品是否還有,不讀取資料庫,速度快,也不會增加資料庫負擔,
經過前面的過濾,超賣的可能性比較低了提前將商品庫存緩存起來,到下單購買的時候,用戶購買了就減1,每次都通過庫存緩存判斷一下,如果為0就顯示已搶完。
五、頁面靜態設計:盡量靜態緩存化【CDN那些這里不做考慮】
第一步①商品詳情頁面,盡量進行緩存,減輕大批量用戶在訪問商品頁面的時候,大量查詢資料庫。
問答問題頁面:全靜態,載入快,無資料庫負擔。
排隊等待頁面:全靜態,載入快,無資料庫負擔。
排隊結束頁面:全靜態,載入快,無資料庫負擔。
㈢ Java中應用線程銀行排隊系統
//您可以使用重入鎖實現排隊。
packagecom.lw;
importjava.util.concurrent.locks.Lock;
importjava.util.concurrent.locks.ReentrantLock;
{
privateintnumber=0;//創建一個變數
privateLocklock=newReentrantLock();//創建重入鎖對象
@Override
publicvoidrun(){
lock.lock();//打開鎖
try{
for(inti=0;i<5;i++){
try{
Thread.sleep(100);//線程休眠0.1秒
}catch(InterruptedExceptione){
e.printStackTrace();
}
//輸出當前線程的名稱和number的值,每次循環之後number的值都會加一
System.out.println(Thread.currentThread().getName()+":"
+number++);
}
}finally{
lock.unlock();//釋放鎖
}
}
publicstaticvoidmain(String[]args){
ReentrantLockDemorun=newReentrantLockDemo();//獲得ReentrantLockDemo對象
Threadthread1=newThread(run);//創建線程1
Threadthread2=newThread(run);//創建線程2
thread1.start();//運行線程1
thread2.start();//運行線程2
}
}
㈣ 如何java實現先接受用戶請求然後排隊處理
收到請求之後同步處理不就行了,當前的請求沒有完成時,其他的請求不處理,等著。
㈤ java的monitor機制中,為什麼阻塞隊列用list等待隊列用set
java阻塞隊列應用於生產者消費者模式、消息傳遞、並行任務執行和相關並發設計的大多數常見使用上下文。
BlockingQueue在Queue介面基礎上提供了額外的兩種類型的操作,分別是獲取元素時等待隊列變為非空和添加元素時等待空間變為可用。
BlockingQueue新增操作的四種形式:
3.2.1.3 HashMap類
對Map類的另外一個實現是HashMap。HashMap使用Hash表數據結構。HashMap假定哈希函數能夠將元素適當的分布在各桶之間,提供一種接近O(1)的查詢和更新操作。但是如果需要對集合進行迭代,則與HashMap的容量和桶的大小有關,因此HashMap的迭代效率不會很高(尤其是你為HashMap設置了較大的容量時)。
與HashMap性能有影響的兩個參數是,初始容量和載入因子。容量是哈希表中桶的數量,初始容量是哈希表在創建時的容量。載入因子是哈希表在容器容量被自動擴充之前,HashMap能夠達到多滿的一種程度。當hash表中的條目數超出了載入因子與當前容量的乘積時,Hash表需要進行rehash操作,此時Hash表將會擴充為以前兩倍的桶數,這個擴充過程需要進行完全的拷貝工作,效率並不高,因此應當盡量避免。合理的設置Hash表的初始容量和載入因子會提高Hash表的性能。HashMap自身不是線程安全的,可以通過Collections的synchronizedMap方法對HashMap進行包裝。
3.2.1.4 ConcurrentHashMap類
ConcurrentHashMap類實現了ConcurrentMap介面,並提供了與HashMap相同的規范和功能。實際上Hash表具有很好的局部可操作性,因為對Hash表的更新操作僅會影響到具體的某個桶(假設更新操作沒有引發rehash),對全局並沒有顯著影響。因此ConcurrentHashMap可以提供很好的並發處理能力。可以通過concurrencyLevel的設置,來控制並發工作線程的數目(默認為16),合理的設置這個值,有時很重要,如果這個值設置的過高,那麼很有可能浪費空間和時間,使用的值過低,又會導致線程的爭用,對數量估計的過高或過低往往會帶來明顯的性能影響。最好在創建ConcurrentHashMap時提供一個合理的初始容量,畢竟rehash操作具有較高的代價。
3.2.2 ConcurrentSkipListSet類
實際上Set和Map從結構來說是很像的,從底層的演算法原理分析,Set和Map應當屬於同源的結構。所以Java也提供了TreeSet和ConcurrentSkipListSet兩種SortedSet,分別適合於非多線程(或低並發多線程)和多線程程序使用。具體的演算法請參考前述的Map相關介紹,這里不在累述。
3.2.3 CopyOnWriteArrayList類
CopyOnWriteArrayList是ArrayList的一個線程安全的變體,其中對於所有的可變操作都是通過對底層數組進行一次新的復制來實現的。
由於可變操作需要對底層的數據進行一次完全拷貝,因此開銷一般較大,但是當遍歷操作遠遠多於可變操作時,此方法將會更有效,這是一種被稱為「快照」的模式,數組在迭代器生存期內不會發生更改,因此不會產生沖突。創建迭代器後,迭代器不會反映列表的添加、移除或者更改。不支持在迭代器上進行remove、set和add操作。CopyOnWriteArraySet與CopyOnWriteArrayList相似,只不過是Set類的一個變體。
3.2.3 Collections提供的線程安全的封裝
Collections中提供了synchronizedCollection、synchronizedList、synchronizedMap、synchronizedSet、synchronizedSortedMap、synchronizedSortedMap等方法可以完成多種集合的線程安全的包裝,如果在並發度不高的情況下,可以考慮使用這些包裝方法,不過由於Concurrent相關的類的出現,已經不這么提倡使用這些封裝了,這些方法有些人稱他們為過時的線程安全機制。
3.2.4簡單總結
提供線程安全的集合簡單概括分為三類,首先,對於並發性要求很高的需求可以選擇以Concurrent開頭的相應的集合類,這些類主要包括:ConcurrentHashMap、ConcurrentLinkedQueue、ConcurrentSkipListMap、ConcurrentSkipSet。其次對於可變操作次數遠遠小於遍歷的情況,可以使用CopyOnWriteArrayList和CopyOnWriteArraySet類。最後,對於並發規模比較小的並行需求可以選擇Collections類中的相應方法對已有集合進行封裝。
此外,本章還對一些集合類的底層實現進行簡單探討,對底層實現的了解有利於對何時使用何種方式作出正確判斷。希望大家能夠將涉及到原理(主要有循環隊列、堆、HashMap、紅黑樹、SkipList)進行仔細研究,這樣才能更深入了解Java為什麼這樣設計類庫,在什麼情況使用,應當如何使用。
㈥ javaweb任務列隊怎麼做
1.在同一時刻,可能有很多任務需要執行,
而程序在同一時刻只能執行一定數量的任務,
當需要執行的任務數超過了程序所能承受的任務數時怎麼辦呢?
這就有了先執行哪些任務,後執行哪些任務的規則。
2.TaskQueue類就定義了這些規則中的一種,它採用的是FIFO(先進先出,英文名是First
In
First
Out)的方式,也就是按照任務到達的先後順序執行。TaskQueue類的定義。
Java任務隊列代碼如下:
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
public class TaskQueue
{
private List<Task>
queue = new LinkedList<Task>();
//
添加一項任務
public synchronized void addTask(Task
task) {
if (task
!= null)
{
queue.add(task);
}
}
//
完成任務後將它從任務隊列中刪除
public synchronized void finishTask(Task
task) {
if (task
!= null)
{
task.setState(Task.State.FINISHED);
queue.remove(task);
}
}
//
取得一項待執行任務
public synchronized Task
getTask() {
Iterator<Task>
it = queue.iterator();
Task
task;
while (it.hasNext())
{
task
= it.next(); //
尋找一個新建的任務
if (Task.State.NEW.equals(task.getState()))
{ //
把任務狀態置為運行中
task.setState(Task.State.RUNNING);
return task;
}
}
return null;
}
}
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
public class TaskQueue
{
private List<Task>
queue = new LinkedList<Task>();
//
添加一項任務
public synchronized void addTask(Task
task) {
if (task
!= null)
{
queue.add(task);
}
}
//
完成任務後將它從任務隊列中刪除
public synchronized void finishTask(Task
task) {
if (task
!= null)
{
task.setState(Task.State.FINISHED);
queue.remove(task);
}
}
//
取得一項待執行任務
public synchronized Task
getTask() {
Iterator<Task>
it = queue.iterator();
Task
task;
while (it.hasNext())
{
task
= it.next(); //
尋找一個新建的任務
if (Task.State.NEW.equals(task.getState()))
{ //
把任務狀態置為運行中
task.setState(Task.State.RUNNING);
return task;
}
}
return null;
}
}
㈦ java學生選課系統 就是做的一個網上學生的選課系統,學生可以在其中進行選課。現在其中有一個排隊功
滿人時把多出來的學生存到他處,然後在退課的函數中加一段,退課時先檢查此時是否人滿,若人滿,則檢查有沒有人排隊,若皆為真則把排隊的第一位學生移到選課人中。
㈧ 用java實現銀行排隊程序,要求模擬銀行的業務排隊系統,要有界面,實現完成的排隊和叫號
import java.awt.Color;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import javax.swing.ButtonGroup;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;
public class BankWaiting extends JFrame implements ActionListener {
int total = 0, now = 0;
boolean is1Ready = false, is2Ready = false, is3Ready = false;
int call1, call2, call3;
JFrame jf;
JLabel jr, jl, jl1, j2, jl2, j3, jl3;
JTextField jr4;
JButton jb, jb1, jb2, j1;
JButton workBut1, workBut2, workBut3;
JPanel jp, jp1, jp2;
public BankWaiting() {
setLayout(null);
jf = new JFrame("銀行叫號程序");// 窗體
jr = new JLabel("請**號到*號窗口辦理業務");
jr.setBounds(300, 10, 800, 50);
jr.setForeground(Color.red);
j1 = new JButton("取號");
j1.addActionListener(this);
jr4 = new JTextField("歡迎");
jr4.setEditable(false);
ButtonGroup bg = new ButtonGroup();
bg.add(j1);
jp = new JPanel();
jl = new JLabel("一號窗口");
jl1 = new JLabel("一號窗口,歡迎你!");
jb = new JButton("下一位");
workBut1 = new JButton("開始辦理");
workBut1.addActionListener(this);
jb.addActionListener(this);
jp.setBackground(Color.pink);
jp.setSize(200, 80);// 大小
jp.setLocation(20, 120); // 位置
jf.setLayout(null);
jp1 = new JPanel();
j2 = new JLabel("二號窗口");
jl2 = new JLabel("二號窗口,歡迎你!");
jb1 = new JButton("下一位");
workBut2 = new JButton("開始辦理");
jb1.addActionListener(this);
workBut2.addActionListener(this);
jp1.setBackground(Color.pink);
jp1.setSize(200, 80);// 大小
jp1.setLocation(250, 120); // 位置
jf.setLayout(null);
jp2 = new JPanel();
j3 = new JLabel("三號窗口");
jl3 = new JLabel("三號窗口,歡迎你!");
jb2 = new JButton("下一位");
workBut3 = new JButton("開始辦理");
workBut3.addActionListener(this);
jb2.addActionListener(this);
jp2.setBackground(Color.pink);
jp2.setSize(200, 80);// 大小
jp2.setLocation(500, 120); // 位置
jf.setLayout(null);
jf.add(jp);
jf.add(jp1);
jf.add(jp2);
jf.add(jr);
jp.add(jl);
jp.add(jl1);
jp.add(jb);
jp.add(workBut1);
jp1.add(j2);
jp1.add(jl2);
jp1.add(jb1);
jp1.add(workBut2);
jp2.add(j3);
jp2.add(jl3);
jp2.add(jb2);
jp2.add(workBut3);
jf.add(j1);
jf.add(jr4);
j1.setBounds(550, 300, 60, 30);
jr4.setBounds(300, 300, 200, 40);
jf.setSize(800, 600);
jf.setVisible(true);
jf.addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent e) {
System.exit(0);
}
});
}
public void actionPerformed(ActionEvent e) {
String s = "";
if (e.getSource() == j1) {
s = "第" + (++total) + "號,前面還有" + (total - now - 1) + "位顧客!";
jr4.setText(s);
}
if (e.getSource() == jb) {
if (this.hasCustomers()) {
s = "請" + (++now) + "號顧客到一號窗口辦理";
call1 = now;
jl1.setText(s);
jr.setText(s);
is1Ready = true;
} else {
s = "當前已經沒有顧客了";
jl1.setText(s);
is1Ready = false;
}
} else if (e.getSource() == jb1) {
if (this.hasCustomers()) {
s = "請" + (++now) + "號顧客到二號窗口辦理";
call2 = now;
jl2.setText(s);
jr.setText(s);
is2Ready = true;
} else {
s = "當前已經沒有顧客了";
jl2.setText(s);
is2Ready = false;
}
} else if (e.getSource() == jb2) {
if (this.hasCustomers()) {
s = "請" + (++now) + "號顧客到三號窗口辦理";
call3 = now;
jl3.setText(s);
jr.setText(s);
is3Ready = true;
} else {
s = "當前已經沒有顧客了";
jl3.setText(s);
is3Ready = false;
}
}
if (e.getSource() == workBut1) {
if (is1Ready) {
s = call1 + "號顧客正在辦理業務。。。";
jl1.setText(s);
is1Ready = false;
}
} else if (e.getSource() == workBut2) {
if (is2Ready) {
s = call2 + "號顧客正在辦理業務。。。";
jl2.setText(s);
is2Ready = false;
}
} else if (e.getSource() == workBut3) {
if (is3Ready) {
s = call3 + "號顧客正在辦理業務。。。";
jl3.setText(s);
is3Ready = false;
}
}
}
public boolean hasCustomers() {
if (now < total) {
return true;
} else {
return false;
}
}
public static void main(String[] args) {
new BankWaiting();
}
}
㈨ 用多線程實現銀行排隊功能java
package com.lw;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
public class ReentrantLockDemo implements Runnable {
private int number = 0;// 創建一個變數
private Lock lock = new ReentrantLock();// 創建重入鎖對象
@Override
public void run() {
lock.lock();// 打開鎖
try {
for (int i = 0; i < 5; i++) {
try {
Thread.sleep(100);// 線程休眠0.1秒
} catch (InterruptedException e) {
e.printStackTrace();
}
// 輸出當前線程的名稱和number的值,每次循環之後number的值都會加一
System.out.println(Thread.currentThread().getName() + ": "
+ number++);
}
} finally {
lock.unlock();// 釋放鎖
}
}
public static void main(String[] args) {
ReentrantLockDemo run = new ReentrantLockDemo();// 獲得ReentrantLockDemo對象
Thread thread1 = new Thread(run);// 創建線程1
Thread thread2 = new Thread(run);// 創建線程2
thread1.start();// 運行線程1
thread2.start();// 運行線程2
}
}
㈩ 求一個java web項目,包含源碼,是銀行排隊系統!
可以通過Bai Hi提示我
有時間可能完成你所面臨的任務
相關的要求也可能提示我
ES:\\
交易提醒:預付定金是詐騙