導航:首頁 > 源碼編譯 > 銷毀隊列的核心源碼

銷毀隊列的核心源碼

發布時間:2022-04-20 07:48:11

java線程池中的核心線程是如何被重復利用的

Java線程池中的核心線程是如何被重復利用的?

引言

在Java開發中,經常需要創建線程去執行一些任務,實現起來也非常方便,但如果並發的線程數量很多,並且每個線程都是執行一個時間很短的任務就結束了,這樣頻繁創建線程就會大大降低系統的效率,因為頻繁創建線程和銷毀線程需要時間。此時,我們很自然會想到使用線程池來解決這個問題。

使用線程池的好處:

Ⅱ C語言關於隊列的問題:是關於求隊列的長度的,問題很簡單,為了大家方便看,我把所有代碼都貼出來

這個鏈表隊列是具備頭節點功能,因此在鏈頭那裡不存放數據,從後面開始算
int QueueLen(LinkQueue Q)//求隊列的長度
{
int length=0;
//QnodePtr p=Q.front->next;//這是為什麼是Q.front
//while(p!=NULL)//為什麼這里是p!=Q.rear??? 不可以是p!=NULL?? //我的一個想法:QnodePtr p=Q.front->next; while(p!=NULL) 不知道為什麼有錯
//1、非循環隊列判斷空的依據,對頭指針與對尾指針相等
//2、既然都調用DestroyQueue釋放內存,後面對隊列的操作沒有任何意義。
//3、只要不調用DestroyQueue,你的演算法也是可以實現長度計算的。
//但是一旦調用DestroyQueuefront=rear=NULL,因此front->next將指向不明地址,發生錯誤.
QnodePtr p=Q.front;
while(p!=Q.rear)
{
length++;
p=p->next;
}
return length;
}

Ⅲ 銷毀隊列的代碼是啥意思解釋下

typedef struct QNode{
QElemType data;
struct QNode *next;//next為指向隊列中下一結點的指針
}QNode,*QueuePtr;

typedef struct{
QueuePtr front,rear;//front&rear are pointers refer to the front and the rear of the queue.
}LinkQueue;//將結構體struct定義為LinkQueue,更符合人類語言理解。

Status Destroyqueue(LinkQueue &Q) {
//隊列Q存在則銷毀Q
while(Q.front){//Q.front是隊列的隊首節點,不為NULL時執行循環
Q.rear=Q.front->next;//Q.rear指向離隊首最近的節點。
free(Q.front);釋放隊首的節點所在內存單元
Q.front=Q.rear;現在Q.front和Q.rear都指向離原來隊首最近的節點。倘若執行Destoryqueue()前節點的個數>=2,則第一次執行次循環後仍滿足循環條件繼續循環,最終整個隊列的內存全部被釋放,隊列被銷毀。(建議在理解的時候畫張圖效果較好)
}

Ⅳ java線程池怎麼實現

要想理解清楚java線程池實現原理,明白下面幾個問題就可以了:

(1):線程池存在哪些狀態,這些狀態之間是如何進行切換的呢?

(2):線程池的種類有哪些?

(3):創建線程池需要哪些參數,這些參數的具體含義是什麼?

(4):將任務添加到線程池之後運行流程?

(5):線程池是怎麼做到重用線程的呢?

(6):線程池的關閉

首先回答第一個問題:線程池存在哪些狀態;

查看ThreadPoolExecutor源碼便知曉:

[java]view plain

Ⅳ 隊列的源代碼(c語言)

以前寫的.你可以看看咯..

class Queue
{
struct Node
{
int a;
Node * next;
};
public:
Queue();
void pump(int b);
void pop();
int getlength();
virtual void print();

private:
Node * head;
Node * rear;
};

void Queue::pump(int b)
{
Node *p1=new Node;
p1->a=b;
p1->next=NULL;
rear->next=p1;
rear=p1;
head->a++;
cout<<setw(2)<<b<<setw(2)<<" 進入隊列 "<<endl;
}
void Queue::pop()
{
Node *p;
p=head->next;
cout<<" "<<setw(2)<<p->a<<setw(2)<<"出隊"<<endl;
head->next=p->next;
delete p;
head->a--;
}
int Queue::getlength()
{
return head->a;
}
void Queue::print()
{
Node *p;
p=head->next;
cout<<"隊列中的元素是:"<<endl;
while(p)
{
cout<<p->a<<" -> ";
p=p->next;
}
cout<<"NULL"<<endl;
}

Queue::Queue()
{
rear=head;

};

Ⅵ java 線程池 工作隊列是如何工作的

使用線程池的好處

1、降低資源消耗

可以重復利用已創建的線程降低線程創建和銷毀造成的消耗。

2、提高響應速度

當任務到達時,任務可以不需要等到線程創建就能立即執行。

3、提高線程的可管理性

線程是稀缺資源,如果無限制地創建,不僅會消耗系統資源,還會降低系統的穩定性,使用線程池可以進行統一分配、調優和監控

線程池的工作原理

首先我們看下當一個新的任務提交到線程池之後,線程池是如何處理的

1、線程池判斷核心線程池裡的線程是否都在執行任務。如果不是,則創建一個新的工作線程來執行任務。如果核心線程池裡的線程都在執行任務,則執行第二步。

2、線程池判斷工作隊列是否已經滿。如果工作隊列沒有滿,則將新提交的任務存儲在這個工作隊列里進行等待。如果工作隊列滿了,則執行第三步

3、線程池判斷線程池的線程是否都處於工作狀態。如果沒有,則創建一個新的工作線程來執行任務。如果已經滿了,則交給飽和策略來處理這個任務

線程池飽和策略

這里提到了線程池的飽和策略,那我們就簡單介紹下有哪些飽和策略:

AbortPolicy

為Java線程池默認的阻塞策略,不執行此任務,而且直接拋出一個運行時異常,切記ThreadPoolExecutor.execute需要try catch,否則程序會直接退出。

DiscardPolicy

直接拋棄,任務不執行,空方法

DiscardOldestPolicy

從隊列裡面拋棄head的一個任務,並再次execute 此task。

CallerRunsPolicy

在調用execute的線程裡面執行此command,會阻塞入口

用戶自定義拒絕策略(最常用)

實現RejectedExecutionHandler,並自己定義策略模式

下我們以ThreadPoolExecutor為例展示下線程池的工作流程圖

3.jpg

關鍵方法源碼分析

我們看看核心方法添加到線程池方法execute的源碼如下:

// //Executes the given task sometime in the future. The task //may execute in a new thread or in an existing pooled thread. // // If the task cannot be submitted for execution, either because this // executor has been shutdown or because its capacity has been reached, // the task is handled by the current {@code RejectedExecutionHandler}. // // @param command the task to execute // @throws RejectedExecutionException at discretion of // {@code RejectedExecutionHandler}, if the task // cannot be accepted for execution // @throws NullPointerException if {@code command} is null // public void execute(Runnable command) { if (command == null) throw new NullPointerException(); // // Proceed in 3 steps: // // 1. If fewer than corePoolSize threads are running, try to // start a new thread with the given command as its first // task. The call to addWorker atomically checks runState and // workerCount, and so prevents false alarms that would add // threads when it shouldn't, by returning false. // 翻譯如下: // 判斷當前的線程數是否小於corePoolSize如果是,使用入參任務通過addWord方法創建一個新的線程, // 如果能完成新線程創建exexute方法結束,成功提交任務 // 2. If a task can be successfully queued, then we still need // to double-check whether we should have added a thread // (because existing ones died since last checking) or that // the pool shut down since entry into this method. So we // recheck state and if necessary roll back the enqueuing if // stopped, or start a new thread if there are none. // 翻譯如下: // 在第一步沒有完成任務提交;狀態為運行並且能否成功加入任務到工作隊列後,再進行一次check,如果狀態 // 在任務加入隊列後變為了非運行(有可能是在執行到這里線程池shutdown了),非運行狀態下當然是需要 // reject;然後再判斷當前線程數是否為0(有可能這個時候線程數變為了0),如是,新增一個線程; // 3. If we cannot queue task, then we try to add a new // thread. If it fails, we know we are shut down or saturated // and so reject the task. // 翻譯如下: // 如果不能加入任務到工作隊列,將嘗試使用任務新增一個線程,如果失敗,則是線程池已經shutdown或者線程池 // 已經達到飽和狀態,所以reject這個他任務 // int c = ctl.get(); // 工作線程數小於核心線程數 if (workerCountOf(c) < corePoolSize) { // 直接啟動新線程,true表示會再次檢查workerCount是否小於corePoolSize if (addWorker(command, true)) return; c = ctl.get(); } // 如果工作線程數大於等於核心線程數 // 線程的的狀態未RUNNING並且隊列notfull if (isRunning(c) && workQueue.offer(command)) { // 再次檢查線程的運行狀態,如果不是RUNNING直接從隊列中移除 int recheck = ctl.get(); if (! isRunning(recheck) && remove(command)) // 移除成功,拒絕該非運行的任務 reject(command); else if (workerCountOf(recheck) == 0) // 防止了SHUTDOWN狀態下沒有活動線程了,但是隊列里還有任務沒執行這種特殊情況。 // 添加一個null任務是因為SHUTDOWN狀態下,線程池不再接受新任務 addWorker(null, false); } // 如果隊列滿了或者是非運行的任務都拒絕執行 else if (!addWorker(command, false)) reject(command); }

Ⅶ 如何:清除隊列內容

可以使用 Purge 方法清除「消息隊列」系統中您有權訪問的任何隊列的內容。例如,假設在本地「消息隊列」客戶端上使用日記隊列記錄送出的所有消息的副本。當日記達到其大小上限時,您可以使用 Purge 方法清除不再需要的項。說明:存儲在日記和死信隊列中的消息計數以隊列所在計算機的配額為限。當到達此配額時,這些隊列停止接受新消息。如果在應用程序中使用日記和死信隊列,定期從這些隊列中清除不再需要的消息很重要。若要刪除隊列的內容,必須在「消息隊列」中具有接收許可權。清除隊列時,它包含的所有消息不發送即被丟棄。可以從代碼或「伺服器資源管理器」中清除隊列的內容。從「伺服器資源管理器」中清除隊列的內容打開「伺服器資源管理器」,然後展開要清除的隊列所在的伺服器節點。提示:如果「伺服器」節點中未列出所需的伺服器,請右擊「伺服器」,單擊「添加伺服器」,輸入伺服器的名稱,然後單擊「確定」。展開「消息隊列」節點。展開要刪除其中的消息的隊列。您將看到該隊列的消息及其關聯日記消息的一個或多個節點。右擊要清除的消息節點,然後單擊「清除消息」。以編程方式清除隊列的內容使用 Purge 方法可以清除適當隊列的內容。代碼應類似於:Dim MessageQueue1 As New System.Messaging.MessageQueue() MessageQueue1.Path = ".\MyQueue" MessageQueue1.Purge() System.Messaging.MessageQueue MessageQueue1 = new System.Messaging.MessageQueue(); MessageQueue1.Path = @".\MyQueue"; MessageQueue1.Purge(); 此代碼示例也可用作 IntelliSense 代碼段。在代碼段選擇器中,此代碼示例位於「Windows 操作系統」>「消息隊列」中。請參見任務 如何:創建隊列其他資源 創建、刪除和管理隊列

Ⅷ 循環隊列的判滿操作的核心代碼是什麼

咨詢記錄 · 回答於2021-10-19

Ⅸ C關於隊列的問題:是關於求隊列的長度的,問題很簡單,為了大家方便看,我把所有代碼都貼出來

#include <stdio.h>
#include <conio.h>
#include <math.h>
#include <stdlib.h>
#define YES 1
#define NO 0

typedef struct qnode
{
int data;
struct qnode *next;
}*QnodePtr,Qnode;

typedef struct linkqueue
{
QnodePtr front;
QnodePtr rear;
}LinkQueue;

void InitQueue(LinkQueue *Q)//初始化隊列
{
if(!(Q->front=Q->rear=(QnodePtr)malloc(sizeof(Qnode))))
exit(OVERFLOW);
Q->front->next=NULL;
}

void DestroyQueue(LinkQueue *Q)//銷毀一個隊列
{
while(Q->front!=NULL)
{
Q->rear=Q->front->next;
free(Q->front);
Q->front=Q->rear;
}
Q=NULL;

}

void ClearQueue(LinkQueue *Q)//清空一個隊列
{
QnodePtr p=NULL,q=NULL;
Q->rear=Q->front;
p=Q->front->next;
Q->front->next=NULL;
while(p)
{
q=p;
p=p->next;
free(q);
}

}

int QueueEmpty(LinkQueue Q)//判斷隊列是否為空
{
if(Q.front==Q.rear)
return YES;
return NO;
}

int GetHead(LinkQueue Q,int *e)//得到隊首元素
{
QnodePtr p=Q.front->next;
if(Q.front==Q.rear)
return NO;
*e=p->data;
return YES;
}

int QueueLen(LinkQueue Q)//求隊列的長度
{
if (Q.front==NULL)//這里加一條語句,假如隊列的頭結點不存在,那麼它的長度自然是0,如果頭結點都不存在了,你還要去訪問它的下一個結點,那麼程序自然就崩潰了
{
return 0;
}
int length=0;
QnodePtr p=Q.front->next;//這是為什麼是Q.front
while(p!=NULL)//為什麼這里是p!=Q.rear??? 不可以是p!=NULL?? //我的一個想法:QnodePtr p=Q.front->next; while(p!=NULL) 不知道為什麼有錯
{
length++;
p=p->next;
}
return length;
}

void QueueInsert(LinkQueue *Q,int e)//向隊尾插入一個元素e
{
QnodePtr p=(QnodePtr)malloc(sizeof(Qnode));
if(!p)
exit(OVERFLOW);
p->data=e;
p->next=NULL;
Q->rear->next=p;
Q->rear=p;
}

int QueueDelete(LinkQueue *Q,int *e)//從隊首刪除一個元素
{
QnodePtr p=NULL;
if(Q->front==Q->rear)
return NO;
p=Q->front->next;
*e=p->data;
Q->front->next=p->next;
if(p==Q->rear)
Q->rear=Q->front;
free(p);
return YES;
}

void QueueTraverse(LinkQueue Q,void (*vi)(int))//對隊列中的每個元素都調用vi函數
{
QnodePtr p=Q.front->next;
while(p)
{
vi(p->data);
p=p->next;
}
}

void Print(int i)
{
printf("%d ",i);
}

int main()
{
LinkQueue Q;
int i;
InitQueue(&Q);
QueueInsert(&Q,10);
QueueInsert(&Q,20);
QueueInsert(&Q,30);
QueueTraverse(Q,Print);
QueueTraverse(Q,Print);
printf("len:\n\na%d\n",QueueLen(Q));
GetHead(Q,&i);
printf("\n\n%d\n",i);
printf("\n\nb%d",QueueEmpty(Q));
DestroyQueue(&Q);
printf("\n\n%d",QueueLen(Q));
getch();
}

要求長度的時候,先要判斷頭結點是否存在。。。

Ⅹ 給個c語言寫的隊列。源碼,最好能在linux下運行的。

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

#define BUF_SIZE 50 //隊列中存儲字元串的個數
struct node
{
char buf[BUF_SIZE];
struct node *next;
};

//入隊(隊列帶頭結點)
void push_value(char *value,struct node *head)
{
struct node *p=head;
while(p->next!=NULL) //查找最後一個元素
{
p=p->next;
}
struct node *new_node=(struct node*)malloc(sizeof(struct node));
strncpy(new_node->buf,value,BUF_SIZE);
new_node->next=NULL;
p->next=new_node; //在隊列尾部插入一個新的元素
}

//出隊,取隊列頭部第一個元素
char *pop_value(struct node *head)
{
struct node *p=head->next; //取第一個元素
head->next=p->next; //刪除隊列中第一個元素
char *result=(char *)malloc(BUF_SIZE*sizeof(char));
strncpy(result,p->buf,BUF_SIZE);
return result;
}

//輸出元素
void print_queue(struct node *head)
{
struct node *p=head->next;
while(p!=NULL)
{
printf("%s\n",p->buf);
p=p->next;
}
}

int main()
{
//帶頭結點的隊列
struct node *head=(struct node*)malloc(sizeof(struct node));
head->next=NULL;
push_value("AAA",head);
push_value("BBB",head);
push_value("CCC",head);

print_queue(head);

char *value=pop_value(head);
printf("pop value is:%s\n",value);

printf("after pop...\n");
print_queue(head);
return 0;
}

閱讀全文

與銷毀隊列的核心源碼相關的資料

熱點內容
如何開一家少兒編程公司 瀏覽:949
光伏計算日照時用什麼app 瀏覽:234
計算階乘的python程序 瀏覽:47
傳奇如何選擇伺服器 瀏覽:574
英雄聯盟光輝和程序員哪個厲害 瀏覽:253
什麼是pojo編程 瀏覽:924
外掛編程視頻 瀏覽:133
學javaapp 瀏覽:12
客戶端無盤如何與伺服器連接 瀏覽:792
狙擊手命令 瀏覽:505
財務防雷指標公式源碼 瀏覽:877
mysql源碼解讀 瀏覽:247
安卓手機如何玩光遇ios版 瀏覽:918
單片機匯編語言C語言 瀏覽:109
雲伺服器4g多少錢一個 瀏覽:440
json雙引號java 瀏覽:402
javades加密演算法 瀏覽:76
程序員母親禮物 瀏覽:603
找裝修設計用什麼app 瀏覽:854
燈塔app是什麼意思 瀏覽:702