最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

詳解Java多線程和IO流的應(yīng)用

 更新時(shí)間:2023年04月11日 10:05:31   作者:CrazyDragon_King  
這篇文章主要介紹了詳解Java多線程和IO流的應(yīng)用,無(wú)論是本地文件復(fù)制,還是網(wǎng)絡(luò)多線程下載,對(duì)于流的使用都是一樣的,需要的朋友可以參考下

Java多線程和流的應(yīng)用

最近看到了一個(gè)例子,是使用多線程的方式下載文件,感覺(jué)很有趣,探索了一下,并且嘗試了使用多線程進(jìn)行本地復(fù)制文件。寫(xiě)完之后,發(fā)現(xiàn)了這兩個(gè)其實(shí)很相似,無(wú)論是本地文件復(fù)制,還是網(wǎng)絡(luò)多線程下載,對(duì)于流的使用都是一樣的。對(duì)于本地文件系統(tǒng)來(lái)說(shuō),輸入流就是從本地文件系統(tǒng)的一個(gè)文件來(lái)獲取,對(duì)于網(wǎng)絡(luò)資源來(lái)說(shuō),是從遠(yuǎn)處服務(wù)器上的一個(gè)文件來(lái)獲取。

注: 雖然這個(gè)多線程下載的代碼,很多人都寫(xiě)過(guò)了,不過(guò)應(yīng)該不是所有人都能理解吧,我這里就再寫(xiě)一遍,哈。

使用多線程的一個(gè)顯而易見(jiàn)的好處就是:利用空閑的 CPU,加快速度。 但是注意不是線程越多越好,雖然好像n個(gè)線程一起下載,每個(gè)線程下載一小部分,下載時(shí)間就會(huì)變?yōu)?/n 了。這是很淺顯的認(rèn)識(shí),就好像一個(gè)人蓋一個(gè)房子需要100天,難道10000個(gè)人,只需要1/10 天一樣了?(這是一個(gè)夸張的說(shuō)法,哈哈?。?/p>

線程之間的切換也是需要系統(tǒng)開(kāi)銷的,線程的數(shù)目還是要控制在一個(gè)合理的范圍內(nèi)才行。

RamdomAccessFile

這個(gè)類比較獨(dú)特,它即可以從文件中讀取數(shù)據(jù),也可以向文件中寫(xiě)入數(shù)據(jù)。但是它不是 OutputStream 和 InputStream 的子類,它是實(shí)現(xiàn)了這兩個(gè)接口 DataOutput 、DataInput 的一個(gè)類。

API 中的介紹:

該類的實(shí)例支持讀取和寫(xiě)入隨機(jī)訪問(wèn)文件。 隨機(jī)訪問(wèn)文件的行為類似于存儲(chǔ)在文件系統(tǒng)中的大量字節(jié)。 有一種游標(biāo),或索引到隱含的數(shù)組,稱為文件指針 ; 輸入操作讀取從文件指針開(kāi)始的字節(jié),并使文件指針超過(guò)讀取的字節(jié)。 如果在讀/寫(xiě)模式下創(chuàng)建隨機(jī)訪問(wèn)文件,則輸出操作也可用; 輸出操作從文件指針開(kāi)始寫(xiě)入字節(jié),并將文件指針提前到寫(xiě)入的字節(jié)。 寫(xiě)入隱式數(shù)組的當(dāng)前端的輸出操作會(huì)導(dǎo)致擴(kuò)展數(shù)組。 文件指針可以通過(guò)讀取getFilePointer方法和由設(shè)置seek方法。

所以,這個(gè)類最重要的就是 seek 方法了,使用 seek 方法,可以控制寫(xiě)入的位置,所以實(shí)現(xiàn)多線程就容易的多了。因此,無(wú)論是本地文件復(fù)制,還是網(wǎng)絡(luò)多線程下載都需要這個(gè)類的作用。

具體思路是: 首先使用 RandomAccessFile 創(chuàng)建一個(gè) File 對(duì)象,然后設(shè)置這個(gè)文件的大小。(對(duì)的,它可以直接設(shè)置文件的大小。)將這個(gè)文件設(shè)置成和要復(fù)制或下載的文件一樣的。(雖然我們并沒(méi)有向這個(gè)文件中寫(xiě)入數(shù)據(jù),但是這個(gè)文件已經(jīng)創(chuàng)建了。)將文件分為若干部分,使用線程復(fù)制或者下載每一部分的內(nèi)容

這有點(diǎn)類似文件的覆蓋,如果一個(gè)已經(jīng)存在的文件,從這個(gè)文件的頭部開(kāi)始寫(xiě)入數(shù)據(jù),一直寫(xiě)到文件的尾部,那么原來(lái)的文件就不存在了,變成了寫(xiě)入的新文件。

設(shè)置文件大?。?/p>

	private static void createOutputFile(File file, long length) throws IOException {
		try (   
			RandomAccessFile raf = new RandomAccessFile(file, "rw")){
			raf.setLength(length);
		}
	}

用圖片來(lái)說(shuō)明: 這個(gè)圖表示一個(gè) 8191 字節(jié)大小的文件: 每一個(gè)部分大小是:8191 / 4 = 2047字節(jié)

將這個(gè)文件的分為四個(gè)部分,每一個(gè)部分使用一個(gè)線程進(jìn)行復(fù)制或下載,其中每一個(gè)箭頭代表一個(gè)線程的開(kāi)始下載位置。我特意將最后一個(gè)部分,沒(méi)有設(shè)置為 1024 byte,這是因?yàn)槲募苌偈钦媚鼙?1024 byte 整除的。(之所以使用 1024 byte,是因?yàn)槲颐看螘?huì)讀取 1024 byte,如果讀取到 1024 byte的話, 否則寫(xiě)入讀取到的相應(yīng)字節(jié)數(shù))。

按照這個(gè)示意圖,每一個(gè)線程下載 2047 byte,那么總共下載的字節(jié)數(shù)是:2047 * 4 = 8188 字節(jié) < 8191 字節(jié)(文件的總大?。?/strong> 所以這就產(chǎn)生了一個(gè)問(wèn)題,下載的字節(jié)數(shù)少于總字節(jié)數(shù),這就是問(wèn)題了,所以必須要下載的字節(jié)數(shù)大于總字節(jié)數(shù)才行。(多了沒(méi)有關(guān)系,因?yàn)槎嘞螺d的部分,會(huì)被后面的給覆蓋掉,不會(huì)產(chǎn)生了問(wèn)題。

所以每個(gè)部分的大小應(yīng)該是:8191 / 4 + 1 = 2048 字節(jié)。(這樣四部分的大小相加是超過(guò)總大小的,不會(huì)發(fā)生數(shù)據(jù)的丟失問(wèn)題。)

所以,這里這個(gè)加 1 是很有必要的。

long size = len / FileCopyUtil.THREAD_NUM + 1;

在這里插入圖片描述

每個(gè)線程下載完成的位置(右邊) 每個(gè)線程,只復(fù)制下載自己的那部分,所以不需要全部下載完所有的內(nèi)容,所以讀取文件數(shù)據(jù)并寫(xiě)入文件的部分,會(huì)多加一個(gè)判斷。

這里增加一個(gè)計(jì)數(shù)器:curlen。它表示是當(dāng)前復(fù)制或者下載的長(zhǎng)度,然后每次讀取后和 size(每部分的大?。┻M(jìn)行比較,如果 curlen 大于 size 就表示相應(yīng)的部分下載完成了(當(dāng)然了,這些都要在數(shù)據(jù)沒(méi)有讀取完的條件下判斷)。

try (
		BufferedInputStream bis = new BufferedInputStream(new FileInputStream(targetFile));
		RandomAccessFile raf = new RandomAccessFile(outputFile, "rw")){
		bis.skip(position);  
		raf.seek(position);  
		int hasRead = 0;
		byte[] b = new byte[1024];
		long curlen = 0;
		while(curlen < size && (hasRead = bis.read(b)) != -1) {
			raf.write(b, 0, hasRead);
			curlen += (long)hasRead;
		}
		System.out.println(n+" "+position+" "+curlen+" "+size);
	} catch (IOException e) {
		e.printStackTrace();
}

在這里插入圖片描述

還有需要注意的是,每個(gè)線程下載的時(shí)候都要: 1. 輸出流設(shè)置文件指針的位置。 2. 輸入流跳過(guò)不需要讀取的字節(jié)。

這是很重要的一步,應(yīng)該是很好理解的。

		bis.skip(position);  
		raf.seek(position);  

多線程本地文件復(fù)制(完整代碼)

package dragon;

import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.RandomAccessFile;

/**
 * 用于進(jìn)行文件復(fù)制,但不是常規(guī)的文件復(fù)制 。
 * 準(zhǔn)備仿照瘋狂Java,寫(xiě)一個(gè)多線程的文件復(fù)制工具。
 * 即可以本地復(fù)制和網(wǎng)絡(luò)復(fù)制
 * */

/**
 * 設(shè)計(jì)思路:
 * 獲取目標(biāo)文件的大小,然后設(shè)置復(fù)制文件的大?。ㄟ@樣做是有好處的),
 * 然后使用將文件分為 n 分,使用 n 個(gè)線程同時(shí)進(jìn)行復(fù)制(這里我將 n 取為 4)。
 * 
 * 可以進(jìn)一步拓展:
 * 加強(qiáng)為斷點(diǎn)復(fù)制功能,即程序中斷以后,
 * 仍然可以繼續(xù)從上次位置恢復(fù)復(fù)制,減少不必要的重復(fù)開(kāi)銷
 * */

public class FileCopyUtil {
	//設(shè)置一個(gè)常量,復(fù)制線程的數(shù)量
	private static final int THREAD_NUM = 4;
	
	private FileCopyUtil() {}
	
	/**
	 * @param targetPath 目標(biāo)文件的路徑
	 * @param outputPath 復(fù)制輸出文件的路徑
	 * @throws IOException 
	 * */
	public static void transferFile(String targetPath, String outputPath) throws IOException {
		File targetFile = new File(targetPath);
		File outputFilePath = new File(outputPath);
		if (!targetFile.exists() || targetFile.isDirectory()) {   //目標(biāo)文件不存在,或者是一個(gè)文件夾,則拋出異常
			throw new FileNotFoundException("目標(biāo)文件不存在:"+targetPath);
		}
		if (!outputFilePath.exists()) {     //如果輸出文件夾不存在,將會(huì)嘗試創(chuàng)建,創(chuàng)建失敗,則拋出異常。
			if(!outputFilePath.mkdir()) {
				throw new FileNotFoundException("無(wú)法創(chuàng)建輸出文件:"+outputPath);
			}
		}
		
		long len = targetFile.length();
		
		File outputFile = new File(outputFilePath, "copy"+targetFile.getName());
		createOutputFile(outputFile, len);    //創(chuàng)建輸出文件,設(shè)置好大小。
		
		long[] position = new long[4];
		//每一個(gè)線程需要復(fù)制文件的起點(diǎn)
		long size = len / FileCopyUtil.THREAD_NUM + 1;
		for (int i = 0; i < FileCopyUtil.THREAD_NUM; i++) {
			position[i] = i*size;
			copyThread(i, position[i], size, targetFile, outputFile);
		}
	}
	
	//創(chuàng)建輸出文件,設(shè)置好大小。
	private static void createOutputFile(File file, long length) throws IOException {
		try (   
			RandomAccessFile raf = new RandomAccessFile(file, "rw")){
			raf.setLength(length);
		}
	}
	
	private static void copyThread(int i, long position, long size, File targetFile, File outputFile) {
		int n = i;   //Lambda 表達(dá)式的限制,無(wú)法使用變量。
		new Thread(()->{
			try (
				BufferedInputStream bis = new BufferedInputStream(new FileInputStream(targetFile));
				RandomAccessFile raf = new RandomAccessFile(outputFile, "rw")){
				bis.skip(position);  //跳過(guò)不需要讀取的字節(jié)數(shù),注意只能先后跳
				raf.seek(position);  //跳到需要寫(xiě)入的位置,沒(méi)有這句話,會(huì)出錯(cuò),但是很難改。
				int hasRead = 0;
				byte[] b = new byte[1024];
				/**
				 * 注意,每個(gè)線程只是讀取一部分?jǐn)?shù)據(jù),不能只以 -1 作為循環(huán)結(jié)束的條件
				 * 循環(huán)退出條件應(yīng)該是兩個(gè),即寫(xiě)入的字節(jié)數(shù)大于需要讀取的字節(jié)數(shù) 或者 文件讀取結(jié)束(最后一個(gè)線程讀取到文件末尾)
				 */
				long curlen = 0;
				while(curlen < size && (hasRead = bis.read(b)) != -1) {
					raf.write(b, 0, hasRead);
					curlen += (long)hasRead;
				}
				System.out.println(n+" "+position+" "+curlen+" "+size);
			} catch (IOException e) {
				e.printStackTrace();
			}
		}).start(); 
	}
}

多線程網(wǎng)絡(luò)下載(完整代碼)

package dragon;

import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.net.URL;
import java.net.URLConnection;

/*
 * 多線程下載文件:
 * 通過(guò)一個(gè) URL 獲取文件輸入流,使用多線程技術(shù)下載這個(gè)文件。
 * */
public class FileDownloadUtil {
	//下載線程數(shù)
	private static final int THREAD_NUM = 4;
	
	/**
	 * @param url 資源位置
	 * @param output 輸出路徑
	 * @throws IOException 
	 * */
	public static void transferFile(String url, String output) throws IOException {
		init(output);
		URL resource = new URL(url);
		URLConnection connection = resource.openConnection();
		
		//獲取文件類型
		String type = connection.getContentType();
		if (type != null) {
			type = "."+type.split("/")[1];
		} else {
			type = "";
		}
		
		//創(chuàng)建文件,并設(shè)置長(zhǎng)度。
		long len = connection.getContentLength();
		String filename = System.currentTimeMillis()+type;
		try (RandomAccessFile raf = new RandomAccessFile(new File(output, filename), "rw")){
			raf.setLength(len);
		}
		
		//為每一個(gè)線程分配相應(yīng)的下載其實(shí)位置
		long size = len / THREAD_NUM + 1;  
		long[] position = new long[THREAD_NUM];

		File downloadFile = new File(output, filename);
		//開(kāi)始下載文件: 4個(gè)線程
		download(url, downloadFile, position, size);
	}
	
	private static void download(String url, File file, long[] position, long size) throws IOException {
		//開(kāi)始下載文件: 4個(gè)線程
		for (int i = 0 ; i < THREAD_NUM; i++) {
			position[i] = i * size;   //每一個(gè)線程下載的起始位置
			int n = i;  // Lambda 表達(dá)式的限制,無(wú)法使用變量
			new Thread(()->{
				URL resource = null;
				URLConnection connection = null;
				try {
					resource = new URL(url);
					connection = resource.openConnection();
				} catch (IOException e) {
					e.printStackTrace();
				}
				
				try (
					BufferedInputStream bis = new BufferedInputStream(connection.getInputStream());
					RandomAccessFile raf = new RandomAccessFile(file, "rw")){  //每個(gè)流一旦關(guān)閉,就不能打開(kāi)了
					raf.seek(position[n]);     //跳到需要下載的位置
					bis.skip(position[n]);   //跳過(guò)不需要下載的部分
					
					int hasRead = 0;
					byte[] b = new byte[1024];	
					long curlen = 0;
					while(curlen < size && (hasRead = bis.read(b)) != -1) {
						raf.write(b, 0, hasRead); 
						curlen += (long)hasRead;
					}
					System.out.println(n+" "+position[n]+" "+curlen+" "+size);
				} catch (FileNotFoundException e) {
					e.printStackTrace();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}) .start();
		}
	}
	
	private static void init(String output) throws FileNotFoundException {
		File path = new File(output);
		if (!path.exists()) {
			if (!path.mkdirs()) {
				throw new FileNotFoundException("無(wú)法創(chuàng)建輸出路徑:"+output);
			}
		} else if (path.isFile()) {
			throw new FileNotFoundException("輸出路徑不是一個(gè)目錄:"+output);
		}
	}	
}

測(cè)試代碼及結(jié)果

因?yàn)檫@個(gè)多線程文件復(fù)制和多線程下載是很相似的,所以就放在一起測(cè)試了。我也想將兩個(gè)寫(xiě)在一個(gè)類里面,這樣可以做成方法的重載調(diào)用。 文件復(fù)制的第一個(gè)參數(shù)可以是 String 或者 URI。 使用這個(gè)作為目標(biāo)文件的參數(shù)。

public File(URI uri)

網(wǎng)絡(luò)文件下載的第一個(gè)參數(shù),可以使用 String 或者是 URL。 不過(guò),因?yàn)橄葘?xiě)的這個(gè)文件復(fù)制,后寫(xiě)的多線程下載,就沒(méi)有做這部分。不過(guò)現(xiàn)在這樣功能也達(dá)到了,可以進(jìn)行本地文件的復(fù)制(多線程)和網(wǎng)絡(luò)文件的下載(多線程)。

package dragon;

import java.io.IOException;

public class FileCopyTest {
	public static void main(String[] args) throws IOException {
		//復(fù)制文件
		long start = System.currentTimeMillis();
		try {
			FileCopyUtil.transferFile("D:\\DB\\download\\timg.jfif", "D:\\DBC");
		} catch (IOException e) {
			e.printStackTrace();
		}
		
		long time = System.currentTimeMillis()-start;
		System.out.println("time: "+time);
		
		//下載文件
		start = System.currentTimeMillis();
		FileDownloadUtil.transferFile("https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1578151056184&di=594a34f05f3587c31d9377a643ddd72e&imgtype=0&src=http%3A%2F%2Fn.sinaimg.cn%2Fsinacn%2Fw1600h1000%2F20180113%2F0bdc-fyqrewh5850115.jpg", "D:\\DB\\download");
		System.out.println("time: "+(System.currentTimeMillis()-start));
	}
}

運(yùn)行截圖: 注意:這里這個(gè)時(shí)間并不是復(fù)制和下載需要的時(shí)間,實(shí)際上它沒(méi)有這個(gè)功能!

注意:雖然兩部分代碼是相同的,但是第三列數(shù)字,卻不是完全相同的,這個(gè)似乎是因?yàn)楸镜睾途W(wǎng)絡(luò)得區(qū)別吧。但是最后得文件是完全相同的,沒(méi)有問(wèn)題得。(我本地文件復(fù)制得是網(wǎng)絡(luò)下載得那張圖片,使用圖片進(jìn)行測(cè)試有一個(gè)好處,就是如果錯(cuò)了一點(diǎn)(字節(jié)數(shù)目不對(duì)),這個(gè)圖片基本上就會(huì)產(chǎn)生問(wèn)題。)

在這里插入圖片描述

產(chǎn)生錯(cuò)誤之后的圖片: 圖片無(wú)法正常顯示,會(huì)出現(xiàn)很多的問(wèn)題,這就說(shuō)明一定是代碼寫(xiě)錯(cuò)了,哈哈。不過(guò)代碼的 bug 有時(shí)候還是很費(fèi)時(shí)間的。

在這里插入圖片描述

總結(jié)

多線程復(fù)制和多線程下載,對(duì)于IO 流的使用都是相同的,所以掌握好IO 流的使用是很關(guān)鍵的一步,這樣就可以做很多很有趣的事情了。將IO流結(jié)合線程和網(wǎng)絡(luò)是一片廣闊的天地,但是我也是最近才看了一點(diǎn)網(wǎng)絡(luò)的知識(shí)。(網(wǎng)絡(luò)是很難的,寫(xiě)這個(gè)多線程下載就遇到了一些網(wǎng)絡(luò)類上面的問(wèn)題。)

使用計(jì)時(shí)器實(shí)現(xiàn)了多線程復(fù)制文件的斷點(diǎn)復(fù)制功能,感興趣的可以了解一下。 多線程斷點(diǎn)復(fù)制

到此這篇關(guān)于詳解Java多線程和IO流的應(yīng)用的文章就介紹到這了,更多相關(guān)Java多線程和IO流內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Spring Boot 實(shí)現(xiàn)配置文件加解密原理

    Spring Boot 實(shí)現(xiàn)配置文件加解密原理

    這篇文章主要介紹了Spring Boot 實(shí)現(xiàn)配置文件加解密原理,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2020-06-06
  • java:程序包org.apache.ibatis.annotations不存在報(bào)錯(cuò)解決

    java:程序包org.apache.ibatis.annotations不存在報(bào)錯(cuò)解決

    這篇文章主要給大家介紹了關(guān)于java:程序包org.apache.ibatis.annotations不存在報(bào)錯(cuò)的解決方法,這個(gè)錯(cuò)誤是我在直接導(dǎo)入springboot項(xiàng)目的時(shí)候報(bào)錯(cuò)的,文中通過(guò)圖文介紹的非常詳細(xì),需要的朋友可以參考下
    2023-04-04
  • JWT 設(shè)置token過(guò)期時(shí)間無(wú)效的解決

    JWT 設(shè)置token過(guò)期時(shí)間無(wú)效的解決

    這篇文章主要介紹了JWT 設(shè)置token過(guò)期時(shí)間無(wú)效的解決方案,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-07-07
  • Java實(shí)現(xiàn)MD5加密的四種方式

    Java實(shí)現(xiàn)MD5加密的四種方式

    MD5是一種廣泛使用的哈希算法,其輸出結(jié)果是一個(gè)128位的二進(jìn)制數(shù),通常以32位十六進(jìn)制數(shù)的形式表示,MD5 的底層實(shí)現(xiàn)涉及多個(gè)復(fù)雜的步驟和算法,本文給大家介紹了Java實(shí)現(xiàn)MD5加密的四種方式,需要的朋友可以參考下
    2025-03-03
  • 利用ssh實(shí)現(xiàn)服務(wù)器文件上傳下載

    利用ssh實(shí)現(xiàn)服務(wù)器文件上傳下載

    這篇文章主要為大家詳細(xì)介紹了如何利用ssh實(shí)現(xiàn)服務(wù)器文件上傳下載,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2016-09-09
  • java實(shí)現(xiàn)相同屬性名稱及相似類型的pojo、dto、vo等互轉(zhuǎn)操作

    java實(shí)現(xiàn)相同屬性名稱及相似類型的pojo、dto、vo等互轉(zhuǎn)操作

    這篇文章主要介紹了java實(shí)現(xiàn)相同屬性名稱及相似類型的pojo、dto、vo等互轉(zhuǎn)操作,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧
    2020-08-08
  • Maven重復(fù)依賴問(wèn)題解決(同一個(gè)jar多個(gè)版本)

    Maven重復(fù)依賴問(wèn)題解決(同一個(gè)jar多個(gè)版本)

    本文主要介紹了Maven重復(fù)依賴問(wèn)題解決(同一個(gè)jar多個(gè)版本),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2023-06-06
  • 使用Java實(shí)現(xiàn)一個(gè)不同難度(高、中、低)的猜數(shù)字游戲

    使用Java實(shí)現(xiàn)一個(gè)不同難度(高、中、低)的猜數(shù)字游戲

    本文介紹了一個(gè)增強(qiáng)版的猜數(shù)字游戲,包括菜單打印、游戲維持、邏輯功能選擇和源代碼展示,游戲通過(guò)隨機(jī)數(shù)生成和邏輯判斷來(lái)維持游戲進(jìn)程,用戶可以選擇不同的難度,源代碼展示了如何實(shí)現(xiàn)這三種不同難度的猜數(shù)字游戲,為玩家?guī)?lái)更多挑戰(zhàn)和樂(lè)趣,需要的朋友可以參考下
    2024-09-09
  • SpringBoot中的maven插件spring-boot-maven-plugin使用

    SpringBoot中的maven插件spring-boot-maven-plugin使用

    這篇文章主要介紹了SpringBoot中的maven插件spring-boot-maven-plugin使用方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-12-12
  • 詳解Java中的流程控制

    詳解Java中的流程控制

    今天帶大家復(fù)習(xí)Java基礎(chǔ)知識(shí),文中對(duì)Java流程控制作了非常詳細(xì)的介紹及代碼示例,對(duì)正在學(xué)習(xí)Java的小伙伴們有很好地幫助,需要的朋友可以參考下
    2021-05-05

最新評(píng)論

信丰县| 文山县| 襄汾县| 永顺县| 济源市| 凤阳县| 万安县| 汶川县| 宁夏| 四会市| 天台县| 宜兰县| 历史| 新乐市| 石狮市| 宝清县| 和田市| 固原市| 广安市| 昌邑市| 甘谷县| 曲周县| 民乐县| 呈贡县| 巫山县| 奎屯市| 临洮县| 全南县| 汕尾市| 商城县| 普陀区| 鲁山县| 富锦市| 郁南县| 霍州市| 大埔区| 怀宁县| 镇康县| 永城市| 韶山市| 吴堡县|