利用Java代码实现并采用多线程加锁方式编写:现有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线程不能一次修改多张图片名,即模拟生产者、消费者,拷贝进一个,修改一个名称。
时间: 2023-11-28 08:48:38 浏览: 71
java多线程实现下载图片并压缩
以下是Java代码实现,采用多线程加锁方式编写:
```java
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
public class CopyRenameImages {
private static final String SRC_DIR = "S/"; // 源文件夹
private static final String DEST_DIR = "D/"; // 目标文件夹
private static final int NUM_IMAGES = 10; // 图片数量
private static Object lock = new Object(); // 加锁对象
public static void main(String[] args) {
// 创建A线程
Thread threadA = new Thread(() -> {
for (int i = 1; i <= NUM_IMAGES; i++) {
synchronized (lock) {
// 拷贝图片
try {
File srcFile = new File(SRC_DIR + getImageName(i));
File destFile = new File(DEST_DIR + getImageName(i));
FileInputStream fis = new FileInputStream(srcFile);
FileOutputStream fos = new FileOutputStream(destFile);
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("Thread A: Copied " + getImageName(i));
lock.notify(); // 唤醒B线程
lock.wait(); // 等待B线程修改文件名
} catch (Exception e) {
e.printStackTrace();
}
}
}
});
// 创建B线程
Thread threadB = new Thread(() -> {
for (int i = 1; i <= NUM_IMAGES; i++) {
synchronized (lock) {
try {
lock.wait(); // 等待A线程拷贝文件
// 修改文件名
File oldFile = new File(DEST_DIR + getImageName(i));
File newFile = new File(DEST_DIR + i + getFileExtension(i));
oldFile.renameTo(newFile);
System.out.println("Thread B: Renamed " + getImageName(i) + " to " + newFile.getName());
lock.notify(); // 唤醒A线程
} catch (Exception e) {
e.printStackTrace();
}
}
}
});
// 启动A、B线程
threadA.start();
threadB.start();
}
// 获取图片名
private static String getImageName(int index) {
char c = (char) ('a' + index - 1);
return String.valueOf(c) + index + getFileExtension(index);
}
// 获取文件扩展名
private static String getFileExtension(int index) {
if (index % 2 == 1) {
return ".jpg";
} else {
return ".png";
}
}
}
```
代码说明:
1. 定义了源文件夹、目标文件夹和图片数量常量。
2. 定义了加锁对象,用于多线程同步。
3. 创建了A线程和B线程,并在A线程中每次拷贝一个图片后等待B线程修改文件名,B线程在修改完文件名后等待A线程拷贝下一个图片。
4. 在A线程和B线程中都使用了`synchronized`关键字加锁,确保同一时刻只有一个线程访问共享资源。
5. 使用`wait()`和`notify()`方法控制线程的执行顺序,实现生产者-消费者模型。
6. 使用`File`类进行文件拷贝和文件名修改。
7. 获取图片名和文件扩展名的方法根据题目要求编写。
注意:在运行程序前,需要先创建S文件夹并添加10张图片。
阅读全文