一区二区三区在线-一区二区三区亚洲视频-一区二区三区亚洲-一区二区三区午夜-一区二区三区四区在线视频-一区二区三区四区在线免费观看

服務(wù)器之家:專注于服務(wù)器技術(shù)及軟件下載分享
分類導(dǎo)航

PHP教程|ASP.NET教程|Java教程|ASP教程|編程技術(shù)|正則表達(dá)式|C/C++|IOS|C#|Swift|Android|JavaScript|易語(yǔ)言|

服務(wù)器之家 - 編程語(yǔ)言 - Java教程 - Java多線程實(shí)現(xiàn)簡(jiǎn)易微信發(fā)紅包的方法實(shí)例

Java多線程實(shí)現(xiàn)簡(jiǎn)易微信發(fā)紅包的方法實(shí)例

2021-08-02 10:42HENU小菜雞 Java教程

這篇文章主要給大家介紹了關(guān)于Java多線程實(shí)現(xiàn)簡(jiǎn)易微信發(fā)紅包的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧

 一、

首先我們先大致了解一下什么是多線程。(書上的解釋)

程序是一段靜態(tài)的代碼,它是應(yīng)用軟件的藍(lán)本。進(jìn)程是程序的一次動(dòng)態(tài)執(zhí)行過程,對(duì)應(yīng)了從代碼加載執(zhí)行,執(zhí)行到執(zhí)行完畢的一個(gè)完整的過程。

線程不是進(jìn)程,線程是比進(jìn)程更小的執(zhí)行單位,一個(gè)進(jìn)程在其執(zhí)行過程中,可以產(chǎn)生多個(gè)線程形成多條執(zhí)行線索,每條線索即每個(gè)線程也有它自身的產(chǎn)生,存在,消亡的過程,和進(jìn)程共享操作系統(tǒng)的資源類似,線程間也可以共享進(jìn)程中的某些內(nèi)存單元,并利用這些共享單元來實(shí)現(xiàn)數(shù)據(jù)交換,實(shí)時(shí)通信與必要的同步操作,但與進(jìn)程不同的是線程的中斷和恢復(fù)更加節(jié)省開支。線程是運(yùn)行在進(jìn)程中的“小進(jìn)程”。

多線程是指一個(gè)應(yīng)用程序中同時(shí)存在幾個(gè)執(zhí)行體,按幾條不同的執(zhí)行線索共同工作的情況。雖然看似是幾個(gè)事件同時(shí)發(fā)生,但其實(shí)計(jì)算機(jī)在任何給定時(shí)刻只能執(zhí)行那些線程中的一個(gè)。為了建立這些線程在同步進(jìn)行的感覺,java虛擬機(jī)快速的把控制從一個(gè)線程切換到另一個(gè)線程。這些線程將被輪流執(zhí)行,使得每個(gè)線程都有機(jī)會(huì)使用cpu資源。

二、

利用單線程實(shí)現(xiàn)的簡(jiǎn)易微信發(fā)紅包

共寫有三種方法,其中第一種,第二種未設(shè)置范圍,紅包數(shù)和人數(shù)為一一對(duì)應(yīng),第三種增添了取值范圍以及計(jì)數(shù)器,人多紅包少有未搶到現(xiàn)象發(fā)生。

(1) 方法一

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
import java.util.scanner;
import com.sun.deploy.security.selectablesecuritymanager;
import java.util.random;
 
public class 簡(jiǎn)易微信發(fā)紅包 {
 public static void main(string[] args) {
  scanner scanner=new scanner(system.in);
  int n;
  double money;
  system.out.println("請(qǐng)輸入您想要發(fā)的紅包數(shù)量");
  n=scanner.nextint();
  system.out.println("請(qǐng)輸入您發(fā)送的紅包金額");
  money=scanner.nextdouble();
  t2 t2=new t2(n,money);
  t2.rob();
 }
}
class t2 {
 public double remain;//有紅包被領(lǐng)取后的余額
 int n;//紅包數(shù)量
 
 t2(int n,double money) {
  this.remain=money;
  this.n=n;
 
 }
 int a=1;
 public void rob() {
 
  while (n > 0) {
   double x2;
 
   if (n != 1) {//因?yàn)樽詈笠粋€(gè)人領(lǐng)取金額為前面人領(lǐng)取紅包后剩下的,所以無需再進(jìn)行隨機(jī)
    x2 = process();//取隨機(jī)金額
    while (judge(x2) != 1) {//判斷取到的隨機(jī)金額是否非法,即無法保證后來每個(gè)紅包領(lǐng)取者領(lǐng)到最低金額0.01
     x2 = process();//若非法則重新取隨機(jī)金額
    }
 
    remain = remain - x2;//當(dāng)領(lǐng)取成功后余額減去領(lǐng)走的金額
    n--;//確保每次判斷人數(shù)為所剩紅包數(shù)減1
    system.out.println("紅包獲得者" + a + "獲得" + x2 + "元");//此處默認(rèn)領(lǐng)取者順序?yàn)樯?/code>
    a++;//控制輸出順序
   }
   else {
    x2 = remain;//因?yàn)樽詈笠粋€(gè)人領(lǐng)取金額為前面人領(lǐng)取紅包后剩下的,所以無需再進(jìn)行隨機(jī)
    string str = string.valueof(x2);
    string str1 = string.format("%.2f", x2);
    x2 = double.parsedouble(str1);
    system.out.println("紅包獲得者" + a + "獲得" + x2 + "元");
    n--;//確保每次判斷人數(shù)為所剩紅包數(shù)減1
   }
 
 
  }
 
 }
 public int judge(double x){//判斷函數(shù)
  if(remain-x>(n-1)*0.01){//確保后來紅包領(lǐng)取者最少能領(lǐng)到最低金額0.01
  
   return 1;
  }
  else return 0;
 }
 
 public double process() {//實(shí)現(xiàn)紅包金額隨機(jī)的函數(shù)
  double x2;
  double x1;
  string str1;
  random random = new random();//隨機(jī)數(shù)為取0到1之間的任意double值
  x1 = remain*random.nextdouble();
   str1= string.format("%.2f",x1);//轉(zhuǎn)化成字符串型用字符串型的format進(jìn)行格式化處理,紅包金額最多取到小數(shù)點(diǎn)后兩位
  x2=double.parsedouble(str1);//再將字符串型數(shù)據(jù)轉(zhuǎn)換成double型
  while(x2==0){//如果所取金額非法則回爐重造
   x1 = remain*random.nextdouble();
   str1= string.format("%.2f",x1);//轉(zhuǎn)化成字符串型用字符串型的format進(jìn)行格式化處理,紅包金額最多取到小數(shù)點(diǎn)后兩位
   x2=double.parsedouble(str1);//再將字符串型數(shù)據(jù)轉(zhuǎn)換成double型
  }
  return x2;
 
 
 }
}

程序運(yùn)行結(jié)果如下

Java多線程實(shí)現(xiàn)簡(jiǎn)易微信發(fā)紅包的方法實(shí)例

(2) 方法二

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
import java.util.random;
import java.util.scanner;
 
public class 簡(jiǎn)易微信發(fā)紅包2 {
 public static void main(string[] args) {
  scanner scanner=new scanner(system.in);
  double money=0;//紅包總金額
  int n;//紅包個(gè)數(shù)
  system.out.println("請(qǐng)輸入您想要發(fā)的紅包數(shù)量");
  n=scanner.nextint();
  system.out.println("請(qǐng)輸入您發(fā)送的紅包金額");
  money=scanner.nextdouble();
  if(money/n==0.01){//當(dāng)所發(fā)金額剛好為每人0.01元時(shí)
   t6 t6=new t6(money,n);
   t6.rob();
  }else{
   t5 t5=new t5(money,n);
   t5.rob();
  }
 }
}
class t5{
 double remain;
 
 int n;
 t5(double money,int n){
  this.remain=money;
  this.n=n;
 }
 int a=1;
 public void rob(){
 
  double max;//最大可領(lǐng)紅包金額
  double x1;//隨機(jī)金額
  double x2;//所得金額
 
while(n>0) {
 if (n != 1) {//前n-1個(gè)紅包領(lǐng)取者領(lǐng)的紅包為隨機(jī)金額紅包
  max = remain - (n - 1) * 0.01;//最大可領(lǐng)紅包金額為剩下的人都獲得最小金額0.01
  random random = new random();
  x1 = (double) random.nextint((int) ((max - 0.01) * 100));
  //用nextint而不用nextdouble的原因是nextdouble無法設(shè)置seed
  //上式中max-0.01,下面的x2+0.01即解決了隨機(jī)數(shù)取0導(dǎo)致紅包獲得者沒搶到錢的問題
  x1 /= 100.0;
  x2 = x1 + 0.01;
  remain = remain - x2;
  n--;
  system.out.println("紅包獲得者" + a + "獲取金額為:" + string.format("%.2f", x2) + "元");
  a++;
 } else {//最后一人領(lǐng)的紅包為前n-1個(gè)人領(lǐng)完后剩下的紅包
 
  system.out.println("紅包獲得者" + a + "獲取金額為:" + string.format("%.2f", remain) + "元");
  n--;
 }
}
 
}
 }
 
 
class t6 {
 double remain;
 int n;
 t6(double money,int n){
  this.remain=money;
  this.n=n;
 }
 
 public void rob(){
  for(int i=1;i<=n;i++){
   system.out.println("紅包獲得者"+i+"獲得了0.01元");
 
 
  }
 }
}

程序運(yùn)行結(jié)果如下:

Java多線程實(shí)現(xiàn)簡(jiǎn)易微信發(fā)紅包的方法實(shí)例
Java多線程實(shí)現(xiàn)簡(jiǎn)易微信發(fā)紅包的方法實(shí)例

(3) 方法三

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
import java.util.random;
import java.util.scanner;
 
public class 簡(jiǎn)易微信發(fā)紅包3 {
  public static void main(string[] args) {
    int p,n;
    double money;
    system.out.println("請(qǐng)輸入您發(fā)送的紅包金額");
    scanner scanner=new scanner(system.in);
    money=scanner.nextdouble();
    system.out.println("請(qǐng)輸入您發(fā)送的紅包數(shù)量");
    n=scanner.nextint();
    system.out.println("請(qǐng)輸入?yún)⑴c搶紅包的人數(shù)");
    p=scanner.nextint();
    t7 t7=new t7(money,n,p);
    t7.rob();
  }
}
 
class t7 {
 
  double money;
  int n,p;
  int count =0;//計(jì)數(shù)器
  double remain;
 t7(double money,int n,int p){
    this.money=money;//總金額
    this.n=n;//紅包數(shù)
   this.p=p;//搶紅包人數(shù)
    this.remain=money;//所剩金額
  }
 
  public void rob() {
    for(int i=1;i<=p;i++) {
      double x1, x2, d;
      string s1, s2;
 
      random random = new random();
      d = money / (n - 1);//設(shè)置范圍讓每次所得金額不超過總數(shù)的1/(n-1),這樣也就避免了一次取得過大導(dǎo)致后面搶的紅包不能保證每個(gè)最少0.01
      x1 = d * random.nextdouble();
      s1 = string.format("%.2f", x1);//轉(zhuǎn)化成字符串型用字符串型的format進(jìn)行格式化處理,紅包金額最多取到小數(shù)點(diǎn)后兩位
      x1 = double.parsedouble(s1);//再將字符串型數(shù)據(jù)轉(zhuǎn)換成double型
      while (x1 == 0 || x1 == money / (n - 1)) {
        x1 = d * random.nextdouble();
        s1 = string.format("%.2f", x1);//轉(zhuǎn)化成字符串型用字符串型的format進(jìn)行格式化處理,紅包金額最多取到小數(shù)點(diǎn)后兩位
        x1 = double.parsedouble(s1);//再將字符串型數(shù)據(jù)轉(zhuǎn)換成double型
      }
      s2 = string.format("%.2f", remain);//轉(zhuǎn)化成字符串型用字符串型的format進(jìn)行格式化處理,紅包金額最多取到小數(shù)點(diǎn)后兩位
      remain = double.parsedouble(s2);//再將字符串型數(shù)據(jù)轉(zhuǎn)換成double型
 
      if (count < n - 1) {//前n-1個(gè)紅包金額為隨機(jī)金額
        system.out.println( "紅包搶奪者"+i+ "搶到了" + s1 + "元");
        remain -= x1;
        count++;
      } else if (count == n - 1) {//第n個(gè)為前n-1個(gè)紅包搶完所剩金額
        system.out.println( "紅包搶奪者"+i+ "搶到了" + s2 + "元");
        count++;
      } else if (count > n - 1) {//紅包被搶完后再來的
        system.out.println( "紅包搶奪者"+i+ "哎呀,手慢了!沒搶到!");
        count++;
      }
    }
  }
}

程序運(yùn)行結(jié)果如下:

Java多線程實(shí)現(xiàn)簡(jiǎn)易微信發(fā)紅包的方法實(shí)例

三、

利用多線程實(shí)現(xiàn)的簡(jiǎn)易微信發(fā)紅包

那么如何創(chuàng)建多線程呢?

1.通過繼承thread類創(chuàng)建多線程

jdk中提供了一個(gè)線程類thread,通過繼承thread類,并重寫thread類中的run()方法便可實(shí)現(xiàn)多線程。

在thread類中,提供了一個(gè)start()方法用于啟動(dòng)新線程,線程啟動(dòng)后,系統(tǒng)會(huì)自動(dòng)調(diào)用run()方法,如果子類重寫了該方法便會(huì)執(zhí)行子類中的方法。

run()方法中就是寫能夠被線程執(zhí)行的程序。如果直接調(diào)用則相當(dāng)于普通方法,必須使用start()方法,才能啟動(dòng)線程,然后再由jvm去調(diào)用該線程的run()方法。

創(chuàng)建并啟動(dòng)多線程的步驟

①定義thread類的子類,并重寫該類的run方法,其方法體代表線程需要完成的任務(wù)。因此常把run方法稱為線程執(zhí)行體。

②創(chuàng)建thread子類的實(shí)例,即創(chuàng)建線程對(duì)象。

③用線程對(duì)象的start方法來啟動(dòng)該線程。

2.通過實(shí)現(xiàn)runnable接口創(chuàng)建多線程

通過繼承thread類實(shí)現(xiàn)了多線程,但是這種方式有一定的局限性。因?yàn)閖ava中只支持單繼承,一個(gè)類一旦繼承了某個(gè)父類就無法再繼承thread類。

thread類提供了另外一個(gè)構(gòu)造方法thread(runnable target),其中runnable是一個(gè)接口,它只有一個(gè)run()方法。

當(dāng)通過thread(runnable target))構(gòu)造方法創(chuàng)建線程對(duì)象時(shí),只需為該方法傳遞一個(gè)實(shí)現(xiàn)了runnable接口的實(shí)例對(duì)象,這樣創(chuàng)建的線程將調(diào)用實(shí)現(xiàn)了runnable接口中的run()方法作為運(yùn)行代碼,而不需要調(diào)用thread類中的run()方法。

創(chuàng)建并啟動(dòng)多線程的步驟

①定義runnable接口的實(shí)現(xiàn)類,并重寫該接口的run方法,該run方法的方法體同樣是該線程的線程執(zhí)行體。

②創(chuàng)建runnable實(shí)現(xiàn)類的實(shí)例,并以此為實(shí)例作為thread的參數(shù)來創(chuàng)建thread對(duì)象,該thread對(duì)象才是真正的線程對(duì)象。

當(dāng)多個(gè)線程使用同一個(gè)共享資源時(shí),可以將處理共享資源的代碼放置在一個(gè)代碼塊中,使用synchronized關(guān)鍵字來修飾,被稱作同步代碼塊

sychronized(lock){
操作共享資源代碼塊
}

其中:lock是一個(gè)鎖對(duì)象,它是同步代碼塊的關(guān)鍵。當(dāng)線程執(zhí)行同步代碼塊時(shí),首先會(huì)檢查鎖對(duì)象的標(biāo)志位,默認(rèn)情況下,標(biāo)志位為1,此時(shí)線程會(huì)執(zhí)行同步代碼塊,同時(shí)將鎖對(duì)象的標(biāo)志位置為0。當(dāng)一個(gè)新的線程執(zhí)行到這段同步代碼塊時(shí),由于鎖對(duì)象的標(biāo)志位為0,新線程會(huì)發(fā)生阻塞,等待當(dāng)前線程執(zhí)行完同步代碼塊后,鎖對(duì)象的標(biāo)志位被置為1,新線程才能進(jìn)入同步代碼塊執(zhí)行其中的代碼。循環(huán)往復(fù),直到共享資源被處理完為止。

同步代碼塊可以有效解決線程的安全問題,當(dāng)把共享資源的操作放在synchronized定義的區(qū)域內(nèi)時(shí),便為這些操作加了同步鎖。

在方法前面同樣可以使用synchronized關(guān)鍵字來修飾,被修飾的方法為同步方法,它能實(shí)現(xiàn)和同步代碼塊同樣的功能,具體語(yǔ)法格式如下:

synchronized 返回值類型 方法名 {}

被synchronized修飾的方法在某一時(shí)刻只允許一個(gè)線程訪問,訪問該方法的其它線程都會(huì)發(fā)生阻塞,直到當(dāng)前線程訪問完畢后,其它線程才有機(jī)會(huì)執(zhí)行方法。

另外

public final string getname():獲取線程的名稱。

public static thread currentthread():返回當(dāng)前正在執(zhí)行的線程對(duì)象,這樣就可以獲取任意方法所在的線程名稱。

thread.currentthread().getname()

現(xiàn)將上面的單線程改成多線程實(shí)現(xiàn)

本篇文章多線程的創(chuàng)建以及實(shí)現(xiàn)用runnable接口實(shí)現(xiàn)

(1)

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
import java.util.scanner;
import com.sun.deploy.security.selectablesecuritymanager;
import java.util.random;
 
public class 微信發(fā)紅包多線程 {
  public static void main(string[] args) {
    scanner scanner=new scanner(system.in);
    int n;
    double money;
    system.out.println("請(qǐng)輸入您想要發(fā)的紅包數(shù)量");
    n=scanner.nextint();
    system.out.println("請(qǐng)輸入您發(fā)送的紅包金額");
    money=scanner.nextdouble();
    t3 t3=new t3(n,money);//創(chuàng)建runnable實(shí)現(xiàn)類的實(shí)例
    for (int j = 1; j <= n; j++) {
      new thread(t3, "紅包獲得者" + j).start();//以上面創(chuàng)建的實(shí)例作為thread的參數(shù)來創(chuàng)建thread對(duì)象,并為thread對(duì)象指定一個(gè)名字,用線程對(duì)象的start方法來啟動(dòng)該線程。
    }
  }
}
class t3 implements runnable {//實(shí)現(xiàn)runnable接口
  public double remain;//有紅包被領(lǐng)取后的余額
  int n;//紅包數(shù)量
 
  public synchronized void run() {//同步方法,在某一時(shí)刻只允許一個(gè)線程訪問,防止數(shù)據(jù)錯(cuò)亂
 
    rob();
  }
 
  t3(int n, double money) {
    this.remain = money;
    this.n = n;
 
  }
 
  int a = n;
 
  public void rob() {
 
 
    double x2;
 
    if (n != 1) {//因?yàn)樽詈笠粋€(gè)人領(lǐng)取金額為前面人領(lǐng)取紅包后剩下的,所以無需再進(jìn)行隨機(jī)
      x2 = process();//取隨機(jī)金額
      while (judge(x2) != 1) {//判斷取到的隨機(jī)金額是否非法,即是否能保證后來每個(gè)紅包領(lǐng)取者領(lǐng)到最低金額0.01
        x2 = process();//若非法則重新取隨機(jī)金額
      }
      remain = remain - x2;//當(dāng)領(lǐng)取成功后余額減去領(lǐng)走的金額
      n--; //確保每次判斷人數(shù)為紅包數(shù)減一
 
    } else {
      x2 = remain;//因?yàn)樽詈笠粋€(gè)人領(lǐng)取金額為前面人領(lǐng)取紅包后剩下的,所以無需再進(jìn)行隨機(jī)
      string str = string.valueof(x2);
      string str1 = string.format("%.2f", x2);
      x2 = double.parsedouble(str1);
 
 
    }
 
    thread th = thread.currentthread();//返回當(dāng)前正在執(zhí)行的線程對(duì)象
    string th_name = th.getname();//獲取線程的名稱
    system.out.println(th_name + "搶到" + x2 + "元");
  }
 
 
  public int judge(double x) {//判斷函數(shù)
    if (remain - x > (n - 1) * 0.01) {//確保后來紅包領(lǐng)取者能領(lǐng)到最低金額0.01
 
      return 1;
    } else return 0;
  }
 
  public double process() {//實(shí)現(xiàn)紅包金額隨機(jī)的函數(shù)
    double x2;
    double x1;
    string str1;
    random random = new random();//隨機(jī)數(shù)為取0到1之間的任意double值
    x1 = remain * random.nextdouble();
    str1 = string.format("%.2f", x1);//轉(zhuǎn)化成字符串型用字符串型的format進(jìn)行格式化處理,紅包金額最多取到小數(shù)點(diǎn)后兩位
    x2 = double.parsedouble(str1);//再將字符串型數(shù)據(jù)轉(zhuǎn)換成double型
    while (x2 == 0) {//如果所取金額非法則回爐重造
      x1 = remain * random.nextdouble();
      str1 = string.format("%.2f", x1);//轉(zhuǎn)化成字符串型用字符串型的format進(jìn)行格式化處理,紅包金額最多取到小數(shù)點(diǎn)后兩位
      x2 = double.parsedouble(str1);//再將字符串型數(shù)據(jù)轉(zhuǎn)換成double型
    }
    return x2;
  }
}

程序運(yùn)行結(jié)果如下:

Java多線程實(shí)現(xiàn)簡(jiǎn)易微信發(fā)紅包的方法實(shí)例

(2)

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
import java.util.random;
import java.util.scanner;
 
public class 簡(jiǎn)易微信發(fā)紅包多線程2 {
  public static void main(string[] args) {
    scanner scanner=new scanner(system.in);
    double money=0;//紅包總金額
    int n;//紅包個(gè)數(shù)
    system.out.println("請(qǐng)輸入您想要發(fā)的紅包數(shù)量");
    n=scanner.nextint();
    system.out.println("請(qǐng)輸入您發(fā)送的紅包金額");
    money=scanner.nextdouble();
    if(money/n==0.01){//當(dāng)所發(fā)金額剛好為每人0.01元時(shí)
      t4 t4=new t4(money,n);
      for(int i=1;i<=n;i++) {
        new thread(t4,"紅包獲得者"+i).start();
      }
    }else{
    t1 t1=new t1(money,n);
      for(int i=1;i<=n;i++) {
        new thread(t1,"紅包獲得者"+i).start();
      }
  }
  }
}
class t1 implements runnable{
  double remain;
 
  int n;
  t1(double money,int n){
    this.remain=money;
    this.n=n;
  }
  @override
  public synchronized void run() {
 
    rob();
  }
  public void rob(){
 
    double max;//最大可領(lǐng)紅包金額
    double x1;//隨機(jī)金額
    double x2;//所得金額
 
    if(n!=1) {//前n-1個(gè)紅包領(lǐng)取者領(lǐng)的紅包為隨機(jī)金額紅包
      max=remain-(n-1)*0.01;//最大可領(lǐng)紅包金額為剩下的人都獲得最小金額0.01
      random random=new random();
     x1=(double)random.nextint((int) ((max-0.01)*100));
     //用nextint而不用nextdouble的原因是nextdouble無法設(shè)置seed
     //上式中max-0.01,下面的x2+0.01即解決了隨機(jī)數(shù)取0導(dǎo)致紅包獲得者沒搶到錢的問題
      x1/=100.0;
      x2=x1+0.01;
      remain=remain-x2;
      n=n-1;
      thread th=thread.currentthread();//獲取當(dāng)前線程
      string th_name=th.getname();//獲取線程名字
      system.out.println(th_name+"獲取金額為:"+string.format("%.2f", x2)+"元");
    }
    else {//最后一人領(lǐng)的紅包為前n-1個(gè)人領(lǐng)完后剩下的紅包
      thread th=thread.currentthread();//獲取當(dāng)前線程
      string th_name=th.getname();//獲取線程名字
      system.out.println(th_name+"獲取金額為:"+string.format("%.2f", remain)+"元");
    }
 
 
 
  }
}
 
class t4 implements runnable{
  double remain;
  int n;
  t4(double money,int n){
    this.remain=money;
    this.n=n;
  }
  public synchronized void run() {
    rob();
  }
  public void rob(){
    thread th=thread.currentthread();//獲取當(dāng)前線程
    string th_name=th.getname();//獲取線程名字
    system.out.println(th_name+"獲取金額為:"+string.format("%.2f", remain/n)+"元");
  }
}

程序運(yùn)行結(jié)果如下:

Java多線程實(shí)現(xiàn)簡(jiǎn)易微信發(fā)紅包的方法實(shí)例
Java多線程實(shí)現(xiàn)簡(jiǎn)易微信發(fā)紅包的方法實(shí)例

(3)

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
import java.util.random;
import java.util.scanner;
 
public class 簡(jiǎn)易微信發(fā)紅包多線程3 {
  public static void main(string[] args) {
    int p,n;
    double money;
    system.out.println("請(qǐng)輸入您發(fā)送的紅包金額");
    scanner scanner=new scanner(system.in);
    money=scanner.nextdouble();
    system.out.println("請(qǐng)輸入您發(fā)送的紅包數(shù)量");
    n=scanner.nextint();
    system.out.println("請(qǐng)輸入?yún)⑴c搶紅包的人數(shù)");
    p=scanner.nextint();
    hh hh=new hh(money,n);
    for (int i=1;i<=p;i++){
      new thread(hh,"第"+i+"個(gè)人").start();
    }
  }
}
 
class hh implements runnable{
 
  double money;
  int n;
  int count =0;//計(jì)數(shù)器
  double remain;
  hh(double money,int n){
    this.money=money;//總金額
    this.n=n;//紅包數(shù)
    this.remain=money;//所剩金額
  }
  @override
  public synchronized void run() {
    rob();
  }
  public void rob(){
 
    double x1,x2,d;
    string s1,s2;
    thread th=thread.currentthread();//獲取當(dāng)前線程
    string th_name=th.getname();//獲取線程名字
    random random=new random();
    d=money/(n-1);//設(shè)置范圍讓每次所得金額不超過總數(shù)的1/(n-1),這樣也就避免了一次取得過大導(dǎo)致后面搶的紅包不能保證每個(gè)最少0.01
   x1=d*random.nextdouble();
    s1=string.format("%.2f",x1);//轉(zhuǎn)化成字符串型用字符串型的format進(jìn)行格式化處理,紅包金額最多取到小數(shù)點(diǎn)后兩位
    x1 = double.parsedouble(s1);//再將字符串型數(shù)據(jù)轉(zhuǎn)換成double型
   while(x1==0||x1==money/(n-1)){
      x1=d*random.nextdouble();
     s1=string.format("%.2f",x1);//轉(zhuǎn)化成字符串型用字符串型的format進(jìn)行格式化處理,紅包金額最多取到小數(shù)點(diǎn)后兩位
     x1 = double.parsedouble(s1);//再將字符串型數(shù)據(jù)轉(zhuǎn)換成double型
   }
    s2= string.format("%.2f",remain);//轉(zhuǎn)化成字符串型用字符串型的format進(jìn)行格式化處理,紅包金額最多取到小數(shù)點(diǎn)后兩位
    remain = double.parsedouble(s2);//再將字符串型數(shù)據(jù)轉(zhuǎn)換成double型
 
    if (count<n-1){//前n-1個(gè)紅包金額為隨機(jī)金額
      system.out.println(th_name+"搶到了"+s1+"元");
      remain-=x1;
      count++;
    }else if (count==n-1){//第n個(gè)為前n-1個(gè)紅包搶完所剩金額
      system.out.println(th_name+"搶到了"+s2+"元");
      count++;
    }else if (count>n-1){//紅包被搶完后再來的
      system.out.println(th_name+"哎呀,手慢了!沒搶到!");
      count++;
    }
  }
 
}

程序運(yùn)行結(jié)果如下:

Java多線程實(shí)現(xiàn)簡(jiǎn)易微信發(fā)紅包的方法實(shí)例

總結(jié)

新手上路,因能力有限,若有不足之處還望大家海涵!

到此這篇關(guān)于java多線程實(shí)現(xiàn)簡(jiǎn)易微信發(fā)紅包的文章就介紹到這了,更多相關(guān)java多線程實(shí)現(xiàn)微信發(fā)紅包內(nèi)容請(qǐng)搜索服務(wù)器之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持服務(wù)器之家!

原文鏈接:https://blog.csdn.net/weixin_46569912/article/details/113308600

延伸 · 閱讀

精彩推薦
主站蜘蛛池模板: 按摩院已婚妇女中文字幕 | 果冻传媒在线完整免费观 | 精品无人区乱码1区2区3区免费 | 91九色丨porny丨制服 | 苍井空av | 亚欧精品在线观看 | 女人张开腿让男人桶爽 | 亚洲精品色婷婷在线影院麻豆 | 欧美夜夜精品一级爽 | 国产白白视频在线观看2 | 亚洲精品久久碰 | 2020最新版的ab片 | 亚洲一区二区三区在线播放 | 精品操| 婷婷色天使在线视频观看 | 精品无人乱码一区二区三区 | 国产精品思瑞在线观看 | 高跟丝袜hdvideossex | 久久综合狠狠综合狠狠 | 四虎国产视频 | chinses台湾男同志hd | 青青久在线视频免费观看 | 欧美午夜精品 | 成人精品视频一区二区在线 | 国产精品乱码高清在线观看 | 奇米精品| 亚洲AV福利天堂一区二区三 | 欧美美女被爆操 | 九九成人免费视频 | 亚洲欧美精品久久 | 亚洲精品第三页 | 男女刺激高清视频在线观看 | 国产久热香蕉在线观看 | 韩国久久精品 | 视频精品一区二区三区 | 色女的乖男人 | a天堂视频| 思敏1一5集国语版免费观看 | 高h禁伦奶水女 | 白丝校花掀起短裙呻吟小说 | 欧美精品一线二线大片 |