小渣飞、 2020-12-21 15:07 采纳率: 87.9%
浏览 73
已采纳

Java 中多线程同步布尔值的问题?

 

找了一天的 Bug 还是找不到是那个地方出了问题,目前线程2卡死,原因是布尔值不同步,可是我使用 static 关键字了,请问为什么在线程1设置为 true 后,线程2还是false,求解决思路

import java.io.*;
import java.util.*;
import java.util.concurrent.ConcurrentLinkedQueue;


public class ThreadCopy {
    private static ConcurrentLinkedQueue<String> queue = new ConcurrentLinkedQueue<String>();
    private static final Scanner scanner = new Scanner(System.in);
    public static String[] types;
    public static File workPath;
    public static File savePath;
    public static int copyErrorCount;
    public static int copySuccessCount;
    public static boolean isFlag = false;

    public static void main(String[] args) throws InterruptedException {

        System.out.println("请输入一个工作路径:");
        workPath = new File(scanner.nextLine());
        System.out.println("请输入一个存储路径:");
        savePath = new File("/Users/jeffrey/test/test2");
        System.out.println("请输入筛选文件的类型,如有多个使用逗号隔开:");
        types = scanner.nextLine().replace(" ", "").split(",");


        if (workPath.exists() && savePath.exists()) {
            Thread t1 = new Thread(new ThreadForFindFile(queue, workPath, types));
            isFlag = true;

            Thread t2 = new Thread(new ThreadForCopyFile(queue, savePath));
            t1.start();
            t2.start();

            while (true) {

                if (!t1.isAlive()) {
                    isFlag = true;
                }
                
                if (!t1.isAlive() && !t2.isAlive()){
                    System.out.println("程序结束");
                    break;
                }
            }

        } else {
            throw new RuntimeException("请输入有效地工作路径或存储路径");
        }
    }
}

class ThreadForFindFile extends Thread {

    private final ConcurrentLinkedQueue<String> queue;
    private final File srcPath;
    private final String[] fileTypes;

    public ThreadForFindFile(ConcurrentLinkedQueue<String> queue, File srcPath, String[] fileTypes) {
        this.queue = queue;
        this.srcPath = srcPath;
        this.fileTypes = fileTypes;
    }

    @Override
    public void run() {
        find(this.srcPath);
    }

    private void find(File srcPath) {
        File[] files = srcPath.listFiles();
        if (files != null) {
            for (File file : files) {
                if (file.isDirectory()) {
                    find(file);
                } else {
                    String[] split = file.toString().split(File.separator);
                    String[] suffix = split[split.length - 1].split("\\.");
                    if (Arrays.toString(fileTypes).contains(suffix[suffix.length - 1])) {
                        this.queue.add(file.toString());
                    }
                }
            }
        }
    }
}

class ThreadForCopyFile extends Thread {
    public static int copyErrorCount = ThreadCopy.copyErrorCount;
    public static int copySuccessCount = ThreadCopy.copySuccessCount;
    public static boolean ThreadOneIsAlive = ThreadCopy.isFlag;

    private final ConcurrentLinkedQueue<String> queue;
    private final File savePath;

    public ThreadForCopyFile(ConcurrentLinkedQueue<String> queue, File savePath) {
        this.queue = queue;
        this.savePath = savePath;
    }

    @Override
    public void run() {
        System.out.println(ThreadOneIsAlive);

        while (!ThreadOneIsAlive) {
            String file = queue.poll();
            try {
                if (file != null) {
                    String[] split = file.split(File.separator);
                    String name = split[split.length - 1];
                    BufferedInputStream bis = new BufferedInputStream(new FileInputStream(file));
                    BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(savePath + File.separator + name));
                    byte[] bytes = new byte[1024];
                    int len;
                    while ((len = bis.read(bytes)) != -1) {
                        bos.write(bytes, 0, len);
                    }
                    copySuccessCount++;
                }

            } catch (Exception e) {
                copyErrorCount++;
                e.printStackTrace();
                break;
            }

        }

    }
}


  • 写回答

3条回答 默认 最新

  • 根由心生 2020-12-21 16:56
    关注
    14 public static  boolean isFlag = true;
    
    
      34          while (true) {
                    if (!t1.isAlive() && !t2.isAlive()){
                        System.out.println("程序结束");
                        break;
                    }
                }
    
    84  ThreadCopy.isFlag = false;
    
    104  while (ThreadCopy.isFlag || !queue.isEmpty() )

    看了下 你想做的是 一个线程找文件 一个线程复制文件吧   对着行号 改掉就行了

     

     

     

     

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(2条)

报告相同问题?

悬赏问题

  • ¥20 docker里部署springboot项目,访问不到扬声器
  • ¥15 netty整合springboot之后自动重连失效
  • ¥15 悬赏!微信开发者工具报错,求帮改
  • ¥20 wireshark抓不到vlan
  • ¥20 关于#stm32#的问题:需要指导自动酸碱滴定仪的原理图程序代码及仿真
  • ¥20 设计一款异域新娘的视频相亲软件需要哪些技术支持
  • ¥15 stata安慰剂检验作图但是真实值不出现在图上
  • ¥15 c程序不知道为什么得不到结果
  • ¥40 复杂的限制性的商函数处理
  • ¥15 程序不包含适用于入口点的静态Main方法