一個簡單的java信號量例子,java 多線程 信號量

本文目錄一覽:

如何使用Java編寫多線程程序(1)

一、簡介1、什麼是線程要說線程,就必須先說說進程,進程就是程序的運行時的一個實例。線程呢可以看作單獨地佔有CPU時間來執行相應的代碼的。對早期的計算機(如DOS)而言,線程既是進程,進程既是進程,因為她是單線程的。當然一個程序可以是多線程的,多線程的各個線程看上去像是並行地獨自完成各自的工作,就像一台一台計算機上運行着多個處理機一樣。在多處理機計算機上實現多線程時,它們確實可以並行工作,而且採用適當的分時策略可以大大提高程序運行的效率。但是二者還是有較大的不同的,線程是共享地址空間的,也就是說多線程可以同時讀取相同的地址空間,並且利用這個空間進行交換數據。 2、為什麼要使用線程為什麼要使用多線程呢?學過《計算機體系結構》的人都知道。將順序執行程序和採用多線程並行執行程序相比,效率是可以大大地提高的。比如,有五個線程thread1, thread2, thread3, thread4, thread5,所耗的CPU時間分別為4,5,1,2,7。(假設CPU輪換周期為4個CPU時間,而且線程之間是彼此獨立的)順序執行需要花費1Array個CPU時間,而並行需要的時間肯定少於1Array個CPU時間,至於具體多少時間要看那些線程是可以同時執行的。這是在非常小規模的情況下,要是面對大規模的進程之間的交互的話,效率可以表現得更高。 3、java中是如何實現多線程的與其他語言不一樣的是,線程的觀念在java是語言中是重要的,根深蒂固的,因為在java語言中的線程系統是java語言自建的, java中有專門的支持多線程的API庫,所以你可以以最快的速度寫一個支持線程的程序。在使用java創建線程的時候,你可以生成一個Thread類或者他的子類對象,並給這個對象發送start()消息(程序可以向任何一個派生自 Runnable 接口的類對象發送 start() 消息的),這樣一來程序會一直執行,直到run返回為止,此時該線程就死掉了。在java語言中,線程有如下特點:§ 在一個程序中而言,主線程的執行位置就是main。而其他線程執行的位置,程序員是可以自定義的。值得注意的是對Applet也是一樣。§ 每個線程執行其代碼的方式都是一次順序執行的。§ 一個線程執行其代碼是與其他線程獨立開來的。如果諸線程之間又相互協作的話,就必須採用一定的交互機制。§ 前面已經說過,線程是共享地址空間的,如果控制不當,這裡很有可能出現死鎖。 各線程之間是相互獨立的,那麼本地變量對一個線程而言就是完全獨立,私有的。所以呢,線程執行時,每個線程都有各自的本地變量拷貝。對象變量(instance variable)在線程之間是可以共享的,這也就是為什麼在java中共享數據對象是如此的好用,但是java線程不能夠武斷地訪問對象變量:他們是需要訪問數據對象的權限的。二、準備知識 在分析這個例子之前,然我們先看看關於線程的幾個概念,上鎖,信號量,和java所提供的API。 上鎖對於大多數的程序而言,他們都需要線程之間相互的通訊來完成整個線程的生命周期,二實現線程之間同步的最簡單的辦法就是上鎖。為了防止相互關聯的兩個線程之間錯誤地訪問共享資源,線程需要在訪問資源的時候上鎖和解鎖,對於鎖而言,有讀鎖,寫鎖和讀寫鎖等不同的同步策略。在java中,所有的對象都有鎖;線程只需要使用synchronized關鍵字就可以獲得鎖。在任一時刻對於給定的類的實例,方法或同步的代碼塊只能被一個線程執行。這是因為代碼在執行之前要求獲得對象的鎖。 信號量通常情況下,多個線程所訪問為數不多的資源,那怎麼控制呢?一個比較非常經典而起非常簡單的辦法就是採用信號量機制。信號量機制的含義就是定義一個信號量,也就是說能夠提供的連接數;當有一個線程佔用了一個連接時,信號量就減一;當一個線程是放了連接時,信號量就加一。

java如何實現信號量集,請注意,是信號量集,而不是信號量,求大神指點

信號量:一個整數;

大於或等於0時代表可供並發進程使用的資源實體數;

小於0時代表正在等待使用臨界區的進程數;

用於互斥的信號量初始值應大於0;

只能通過P、V原語操作而改變;

信號量元素組成:

1、表示信號量元素的值;

2、最後操作信號量元素的進程ID

3、等待信號量元素值+1的進程數;

4、等待信號量元素值為0的進程數;

二、主要函數

1.1 創建信號量

int semget(

key_t key, //標識信號量的關鍵字,有三種方法:1、使用IPC——PRIVATE讓系統產生,

// 2、挑選一個隨機數,3、使用ftok從文件路徑名中產生

int nSemes, //信號量集中元素個數

int flag //IPC_CREAT;IPC_EXCL 只有在信號量集不存在時創建

)

成功:返回信號量句柄

失敗:返回-1

1.2 使用ftok函數根據文件路徑名產生一個關鍵字

key_t ftok(const char *pathname,int proj_id);

路徑名稱必須有相應權限

1.3 控制信號量

int semctl(

int semid, //信號量集的句柄

int semnum, //信號量集的元素數

int cmd, //命令

/*union senum arg */… //

)

成功:返回相應的值

失敗:返回-1

命令詳細說明:

cmd: IPC_RMID 刪除一個信號量

IPC_EXCL 只有在信號量集不存在時創建

IPC_SET 設置信號量的許可權

SETVAL 設置指定信號量的元素的值為 agc.val

GETVAL 獲得一個指定信號量的值

GETPID 獲得最後操縱此元素的最後進程ID

GETNCNT 獲得等待元素變為1的進程數

GETZCNT 獲得等待元素變為0的進程數

用java編寫交通信號燈

按照你的要求編寫的紅綠燈程序,你看看吧,比較簡單。

完整的程序如下:

import java.awt.*;

import java.awt.event.*;

import javax.swing.*;

import java.awt.Graphics;

public class TrafficLight extends JFrame{

JRadioButton jrbYellow,jrbGreen,jrbRed;

int flag=0;

jpNewPanel jpNewPanel;

public static void main(String[] args){

TrafficLight frame=new TrafficLight();

frame.setSize(500,200);

frame.setLocationRelativeTo(null);

frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

frame.setTitle(“TrafficLight”);

frame.setVisible(true);

}

public TrafficLight(){

jpNewPanel=new jpNewPanel();

add(jpNewPanel,BorderLayout.CENTER);

JPanel jpRadioButtons=new JPanel();

jpRadioButtons.setLayout(new GridLayout(1,3));

jpRadioButtons.add(jrbYellow=new JRadioButton(“Yellow”));

jpRadioButtons.add(jrbGreen=new JRadioButton(“Green”));

jpRadioButtons.add(jrbRed=new JRadioButton(“Red”));

add(jpRadioButtons,BorderLayout.SOUTH);

ButtonGroup group=new ButtonGroup();

group.add(jrbYellow);

group.add(jrbGreen);

group.add(jrbRed);

jrbYellow.addActionListener(new ActionListener(){

public void actionPerformed(ActionEvent e){

flag=2;

jpNewPanel.repaint();

}

});

jrbGreen.addActionListener(new ActionListener(){

public void actionPerformed(ActionEvent e){

flag=1;

jpNewPanel.repaint();

}

});

jrbRed.addActionListener(new ActionListener(){

public void actionPerformed(ActionEvent e){

flag=3;

jpNewPanel.repaint();

}

});

}

class jpNewPanel extends JPanel{

protected void paintComponent(Graphics g){

super.paintComponent(g);

g.drawRect(0,0,40,100);

g.drawOval(10,10,20,20);

g.drawOval(10,40,20,20);

g.drawOval(10,70,20,20);

if(flag==1){

g.setColor(Color.GREEN);

g.fillOval(10, 70, 20, 20);

}

else if(flag==2){

g.setColor(Color.YELLOW);

g.fillOval(10, 40, 20, 20);

}

else if(flag==3){

g.setColor(Color.RED);

g.fillOval(10, 10, 20, 20);

}

}

}

}

Semaphore信號量的底層原理

Semaphore(信號量) 是一個線程同步結構,用於在線程間傳遞信號,以避免出現信號丟失(譯者註:下文會具體介紹),或者像鎖一樣用於保護一個關鍵區域。自從5.0開始,jdk在java.util.concurrent包里提供了Semaphore 的官方實現,因此大家不需要自己去實現Semaphore。但是還是很有必要去熟悉如何使用Semaphore及其背後的原理

本文的涉及的主題如下:

一、簡單的Semaphore實現

下面是一個信號量的簡單實現:

查看源代碼打印幫助

Take方法發出一個被存放在Semaphore內部的信號,而Release方法則等待一個信號,當其接收到信號後,標記位signal被清空,然後該方法終止。

使用這個semaphore可以避免錯失某些信號通知。用take方法來代替notify,release方法來代替wait。如果某線程在調用release等待之前調用take方法,那麼調用release方法的線程仍然知道take方法已經被某個線程調用過了,因為該Semaphore內部保存了take方法發出的信號。而wait和notify方法就沒有這樣的功能。

當用semaphore來產生信號時,take和release這兩個方法名看起來有點奇怪。這兩個名字來源於後面把semaphore當做鎖的例子,後面會詳細介紹這個例子,在該例子中,take和release這兩個名字會變得很合理。

二、可計數的Semaphore

上面提到的Semaphore的簡單實現並沒有計算通過調用take方法所產生信號的數量。可以把它改造成具有計數功能的Semaphore。下面是一個可計數的Semaphore的簡單實現。

三、有上限的Semaphore

上面的CountingSemaphore並沒有限制信號的數量。下面的代碼將CountingSemaphore改造成一個信號數量有上限的BoundedSemaphore。

在BoundedSemaphore中,當已經產生的信號數量達到了上限,take方法將阻塞新的信號產生請求,直到某個線程調用release方法後,被阻塞於take方法的線程才能傳遞自己的信號。

原創文章,作者:XTJW,如若轉載,請註明出處:https://www.506064.com/zh-hant/n/142789.html

(0)
打賞 微信掃一掃 微信掃一掃 支付寶掃一掃 支付寶掃一掃
XTJW的頭像XTJW
上一篇 2024-10-14 18:42
下一篇 2024-10-14 18:42

相關推薦

  • Python簡單數學計算

    本文將從多個方面介紹Python的簡單數學計算,包括基礎運算符、函數、庫以及實際應用場景。 一、基礎運算符 Python提供了基礎的算術運算符,包括加(+)、減(-)、乘(*)、除…

    編程 2025-04-29
  • Python滿天星代碼:讓編程變得更加簡單

    本文將從多個方面詳細闡述Python滿天星代碼,為大家介紹它的優點以及如何在編程中使用。無論是剛剛接觸編程還是資深程序員,都能從中獲得一定的收穫。 一、簡介 Python滿天星代碼…

    編程 2025-04-29
  • Python多線程讀取數據

    本文將詳細介紹多線程讀取數據在Python中的實現方法以及相關知識點。 一、線程和多線程 線程是操作系統調度的最小單位。單線程程序只有一個線程,按照程序從上到下的順序逐行執行。而多…

    編程 2025-04-29
  • Python海龜代碼簡單畫圖

    本文將介紹如何使用Python的海龜庫進行簡單畫圖,並提供相關示例代碼。 一、基礎用法 使用Python的海龜庫,我們可以控制一個小海龜在窗口中移動,並利用它的“畫筆”在窗口中繪製…

    編程 2025-04-29
  • Python櫻花樹代碼簡單

    本文將對Python櫻花樹代碼進行詳細的闡述和講解,幫助讀者更好地理解該代碼的實現方法。 一、簡介 櫻花樹是一種圖形效果,它的實現方法比較簡單。Python中可以通過turtle這…

    編程 2025-04-28
  • Python大神作品:讓編程變得更加簡單

    Python作為一種高級的解釋性編程語言,一直被廣泛地運用於各個領域,從Web開發、遊戲開發到人工智能,Python都扮演着重要的角色。Python的代碼簡潔明了,易於閱讀和維護,…

    編程 2025-04-28
  • Python計數循環例子用法介紹

    在這篇文章中,我們將為您提供有關Python計數循環的一些詳細信息,並為您提供示例和代碼,讓您更深入地了解如何使用Python進行計數循環。 一、什麼是計數循環? 計數循環是編程中…

    編程 2025-04-28
  • 用Python實現簡單爬蟲程序

    在當今時代,互聯網上的信息量是爆炸式增長的,其中很多信息可以被利用。對於數據分析、數據挖掘或者其他一些需要大量數據的任務,我們可以使用爬蟲技術從各個網站獲取需要的信息。而Pytho…

    編程 2025-04-28
  • 如何製作一個簡單的換裝遊戲

    本文將從以下幾個方面,為大家介紹如何製作一個簡單的換裝遊戲: 1. 遊戲需求和界面設計 2. 使用HTML、CSS和JavaScript開發遊戲 3. 實現遊戲的基本功能:拖拽交互…

    編程 2025-04-27
  • Guava Limiter——限流器的簡單易用

    本文將從多個維度對Guava Limiter進行詳細闡述,介紹其定義、使用方法、工作原理和案例應用等方面,並給出完整的代碼示例,希望能夠幫助讀者更好地了解和使用該庫。 一、定義 G…

    編程 2025-04-27

發表回復

登錄後才能評論