Java多線程實(shí)現(xiàn)簡(jiǎn)易微信發(fā)紅包的方法實(shí)例
一、
首先我們先大致了解一下什么是多線程。(書上的解釋)
程序是一段靜態(tài)的代碼,它是應(yīng)用軟件的藍(lán)本。進(jìn)程是程序的一次動(dòng)態(tài)執(zhí)行過(guò)程,對(duì)應(yīng)了從代碼加載執(zhí)行,執(zhí)行到執(zhí)行完畢的一個(gè)完整的過(guò)程。
線程不是進(jìn)程,線程是比進(jìn)程更小的執(zhí)行單位,一個(gè)進(jìn)程在其執(zhí)行過(guò)程中,可以產(chǎn)生多個(gè)線程形成多條執(zhí)行線索,每條線索即每個(gè)線程也有它自身的產(chǎn)生,存在,消亡的過(guò)程,和進(jìn)程共享操作系統(tǒng)的資源類似,線程間也可以共享進(jìn)程中的某些內(nèi)存單元,并利用這些共享單元來(lá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)行的感覺(jué),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) 方法一
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)取紅包后剩下的,所以無(wú)需再進(jìn)行隨機(jī)
x2 = process();//取隨機(jī)金額
while (judge(x2) != 1) {//判斷取到的隨機(jī)金額是否非法,即無(wú)法保證后來(lái)每個(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)樯?
a++;//控制輸出順序
}
else {
x2 = remain;//因?yàn)樽詈笠粋€(gè)人領(lǐng)取金額為前面人領(lǐng)取紅包后剩下的,所以無(wú)需再進(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ái)紅包領(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é)果如下

(2) 方法二
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無(wú)法設(shè)置seed
//上式中max-0.01,下面的x2+0.01即解決了隨機(jī)數(shù)取0導(dǎo)致紅包獲得者沒(méi)搶到錢的問(wèn)題
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é)果如下:


(3) 方法三
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è)置范圍讓每次所得金額不超過(guò)總數(shù)的1/(n-1),這樣也就避免了一次取得過(guò)大導(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) {//紅包被搶完后再來(lái)的
System.out.println( "紅包搶奪者"+i+ "哎呀,手慢了!沒(méi)搶到!");
count++;
}
}
}
}
程序運(yùn)行結(jié)果如下:

三、
利用多線程實(shí)現(xiàn)的簡(jiǎn)易微信發(fā)紅包
那么如何創(chuàng)建多線程呢?
1.通過(guò)繼承thread類創(chuàng)建多線程
JDK中提供了一個(gè)線程類Thread,通過(guò)繼承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方法來(lái)啟動(dòng)該線程。
2.通過(guò)實(shí)現(xiàn)Runnable接口創(chuàng)建多線程
通過(guò)繼承Thread類實(shí)現(xiàn)了多線程,但是這種方式有一定的局限性。因?yàn)镴ava中只支持單繼承,一個(gè)類一旦繼承了某個(gè)父類就無(wú)法再繼承Thread類。
Thread類提供了另外一個(gè)構(gòu)造方法Thread(Runnable target),其中Runnable是一個(gè)接口,它只有一個(gè)run()方法。
當(dāng)通過(guò)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ù)來(lái)創(chuàng)建Thread對(duì)象,該Thread對(duì)象才是真正的線程對(duì)象。
當(dāng)多個(gè)線程使用同一個(gè)共享資源時(shí),可以將處理共享資源的代碼放置在一個(gè)代碼塊中,使用synchronized關(guān)鍵字來(lái)修飾,被稱作同步代碼塊:
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ù),直到共享資源被處理完為止。
同步代碼塊可以有效解決線程的安全問(wèn)題,當(dāng)把共享資源的操作放在synchronized定義的區(qū)域內(nèi)時(shí),便為這些操作加了同步鎖。
在方法前面同樣可以使用synchronized關(guān)鍵字來(lái)修飾,被修飾的方法為同步方法,它能實(shí)現(xiàn)和同步代碼塊同樣的功能,具體語(yǔ)法格式如下:
synchronized 返回值類型 方法名 {}
被synchronized修飾的方法在某一時(shí)刻只允許一個(gè)線程訪問(wèn),訪問(wèn)該方法的其它線程都會(huì)發(fā)生阻塞,直到當(dāng)前線程訪問(wèn)完畢后,其它線程才有機(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)
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ù)來(lái)創(chuàng)建Thread對(duì)象,并為Thread對(duì)象指定一個(gè)名字,用線程對(duì)象的start方法來(lái)啟動(dòng)該線程。
}
}
}
class T3 implements Runnable {//實(shí)現(xiàn)runnable接口
public double remain;//有紅包被領(lǐng)取后的余額
int n;//紅包數(shù)量
public synchronized void run() {//同步方法,在某一時(shí)刻只允許一個(gè)線程訪問(wèn),防止數(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)取紅包后剩下的,所以無(wú)需再進(jìn)行隨機(jī)
x2 = process();//取隨機(jī)金額
while (judge(x2) != 1) {//判斷取到的隨機(jī)金額是否非法,即是否能保證后來(lái)每個(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)取紅包后剩下的,所以無(wú)需再進(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ái)紅包領(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é)果如下:

(2)
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無(wú)法設(shè)置seed
//上式中max-0.01,下面的x2+0.01即解決了隨機(jī)數(shù)取0導(dǎo)致紅包獲得者沒(méi)搶到錢的問(wèn)題
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é)果如下:


(3)
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è)置范圍讓每次所得金額不超過(guò)總數(shù)的1/(n-1),這樣也就避免了一次取得過(guò)大導(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){//紅包被搶完后再來(lái)的
System.out.println(th_name+"哎呀,手慢了!沒(méi)搶到!");
count++;
}
}
}
程序運(yùn)行結(jié)果如下:

總結(jié)
新手上路,因能力有限,若有不足之處還望大家海涵!
到此這篇關(guān)于Java多線程實(shí)現(xiàn)簡(jiǎn)易微信發(fā)紅包的文章就介紹到這了,更多相關(guān)Java多線程實(shí)現(xiàn)微信發(fā)紅包內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Java 客戶端向服務(wù)端上傳mp3文件數(shù)據(jù)的實(shí)例代碼
這篇文章主要介紹了Java 客戶端向服務(wù)端上傳mp3文件數(shù)據(jù)的實(shí)例代碼,非常不錯(cuò),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2018-09-09
java經(jīng)典問(wèn)題:連個(gè)字符串互為回環(huán)變位
連個(gè)字符串互為回環(huán)變位經(jīng)常出現(xiàn)在java程序員面試中,這個(gè)是考驗(yàn)程序員的解題思路和方法的最經(jīng)典的一題,小編為大家詳細(xì)分析一下,一起來(lái)學(xué)習(xí)吧。2017-11-11
Java的MyBatis+Spring框架中使用數(shù)據(jù)訪問(wèn)對(duì)象DAO模式的方法
Data Access Object數(shù)據(jù)訪問(wèn)對(duì)象模式在Java操作數(shù)據(jù)庫(kù)部分的程序設(shè)計(jì)中經(jīng)常被使用到,這里我們就來(lái)看一下Java的MyBatis+Spring框架中使用數(shù)據(jù)訪問(wèn)對(duì)象DAO模式的方法:2016-06-06
eclipse怎么引入spring boot項(xiàng)目插件的方法
這篇文章主要介紹了eclipse怎么引入spring boot項(xiàng)目插件的方法,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2019-06-06
Spring BeanFactory和FactoryBean區(qū)別解析
這篇文章主要介紹了Spring BeanFactory和FactoryBean區(qū)別解析,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-03-03
java提取json中某個(gè)數(shù)組的所有值方法
下面小編就為大家分享一篇java提取json中某個(gè)數(shù)組的所有值方法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2018-03-03

