现有A、B两个线程,文件夹S中有10张图片,图片名分别为a1.jpg或a1.png、b2.jpg或b2.png、c3..d4..以此类推..k10.jpg或k10.png,A线程任务是往文件夹D中拷贝图片,B线程任务是每有一张图片拷贝进来,需将图片名称改成1.jpg或1.png。。以此类推到10.png或10.jpg,然后程序退出。要求:A线程不能一次拷贝多张图片,B线程不能一次修改多张图片名,即模拟生产者、消费者,拷贝进一个,修改一个名称,此题目需要用实验报告形式完成。
时间: 2024-02-20 20:58:47 浏览: 19
好的,根据您的需求,我来为您编写Java多线程程序,实现A线程往文件夹D中拷贝图片,B线程修改图片名称的任务。这里我们采用生产者-消费者模型,A线程作为生产者,B线程作为消费者。
首先是A线程的代码,用于往文件夹D中拷贝图片:
```java
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
public class AThread extends Thread {
private File folderS;
private File folderD;
public AThread(File folderS, File folderD) {
this.folderS = folderS;
this.folderD = folderD;
}
@Override
public void run() {
// 循环遍历文件夹S中的图片,并拷贝到文件夹D中
for (int i = 1; i <= 10; i++) {
// 构造源文件和目标文件的路径
String srcPath = folderS.getPath() + File.separator + (char)('a' + i - 1) + i + (i <= 5 ? ".jpg" : ".png");
String destPath = folderD.getPath() + File.separator + (char)('a' + i - 1) + i + (i <= 5 ? ".jpg" : ".png");
try {
// 创建文件输入流和输出流
FileInputStream fis = new FileInputStream(srcPath);
FileOutputStream fos = new FileOutputStream(destPath);
// 定义缓冲区
byte[] buffer = new byte[1024];
int len;
// 逐个字节地读取源文件并写入目标文件
while ((len = fis.read(buffer)) != -1) {
fos.write(buffer, 0, len);
}
// 关闭输入流和输出流
fis.close();
fos.close();
// 打印拷贝成功的文件名
System.out.println("A线程拷贝了图片:" + destPath);
// 等待B线程修改文件名
synchronized (Main.lock) {
Main.lock.notify();
Main.lock.wait();
}
} catch (IOException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
```
在A线程的run()方法中,我们使用循环遍历文件夹S中的图片,并逐个拷贝到文件夹D中。在拷贝完成后,我们使用synchronized关键字来获取Main类中定义的锁,并调用wait()方法等待B线程修改文件名。在B线程修改完文件名后,我们再调用notify()方法唤醒A线程,继续拷贝下一张图片。
接下来是B线程的代码,用于修改文件名:
```java
import java.io.File;
public class BThread extends Thread {
private File folderD;
public BThread(File folderD) {
this.folderD = folderD;
}
@Override
public void run() {
// 循环遍历文件夹D中的图片,并修改文件名
for (int i = 1; i <= 10; i++) {
// 构造旧文件名和新文件名的路径
String oldPath = folderD.getPath() + File.separator + (char)('a' + i - 1) + i + (i <= 5 ? ".jpg" : ".png");
String newPath = folderD.getPath() + File.separator + i + (i <= 5 ? ".jpg" : ".png");
// 创建旧文件和新文件
File oldFile = new File(oldPath);
File newFile = new File(newPath);
// 修改文件名
if (oldFile.renameTo(newFile)) {
// 打印修改成功的文件名
System.out.println("B线程修改了文件名:" + oldPath + " -> " + newPath);
} else {
System.out.println("B线程修改文件名失败:" + oldPath);
}
// 唤醒A线程继续拷贝下一张图片
synchronized (Main.lock) {
Main.lock.notify();
}
}
}
}
```
在B线程的run()方法中,我们使用循环遍历文件夹D中的图片,并逐个修改文件名。在修改完成后,我们使用synchronized关键字来获取Main类中定义的锁,并调用notify()方法唤醒A线程,让它继续拷贝下一张图片。
最后是Main类的代码,用于启动A线程和B线程:
```java
import java.io.File;
public class Main {
public static Object lock = new Object();
public static void main(String[] args) {
// 创建文件夹S和文件夹D
File folderS = new File("S");
File folderD = new File("D");
if (!folderS.exists()) {
folderS.mkdirs();
}
if (!folderD.exists()) {
folderD.mkdirs();
}
// 创建A线程和B线程
AThread aThread = new AThread(folderS, folderD);
BThread bThread = new BThread(folderD);
// 启动A线程和B线程
aThread.start();
bThread.start();
}
}
```
在Main类的main()方法中,我们先创建文件夹S和文件夹D,然后创建A线程和B线程,并启动它们。
综上所述,以上就是本题的完整代码实现。您可以将代码复制到Java IDE中运行,观察输出结果。