【Java】单例模式:U盘监听器和简单实现

单例模式:只能有一个实例
检测到有U盘插入时,查找设备中的所有文件

在U盘插入之前先获取系统开始的盘符数。两个线程分别为生产者和消费者
生产者:循环检测系统盘符,若判断出盘符数增多,则该线程等待并唤醒消费者。

消费者:一直处于等待状态,直到被生产者唤醒。

单例:
public class UDiskMonitor {
	//设为私有
    private static final Logger logger = LoggerFactory.getLogger(UDiskMonitor.class);
    private static UDiskMonitor sUsbDiskMonitor;

    private UDiskMonitor() {
        File[] dir = File.listRoots();//File类方法:获取盘符
        count = dir.length;
        ResourceFileRunnable rf = new ResourceFileRunnable(count);
        Thread t1 = new Thread(new ProducerUsbDisk(rf));//生产者
        Thread t2 = new Thread(new ConsumerUsbDisk(rf));//消费者
        t1.start();
        t2.start();
    }
	
	//获取或者创建实例
    public static UDiskMonitor getInstance() {
        if(sUsbDiskMonitor == null) {
            sUsbDiskMonitor = new UsbDiskMonitor();
        }

        return sUsbDiskMonitor;
    }

    public static int count = 0;

    public static void main(String[] args) throws Exception {
        UDiskMonitor.getInstance();
    }


}
生产者

因为不需要返回值,所以采用实现Runnable接口的run()方法

class ProducerUsbDisk implements Runnable {

    private ResourceFileRunnable rf = null;

    public ProducerUsbDisk(ResourceFileRunnable rf) {
        this.rf = rf;
    }

    @Override
    public void run() {
        while (true) {
            rf.searchFile();//获取盘符
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}
消费者
class ConsumerUsbDisk implements Runnable {
 
	private ResourceFileRunnable rf = null;
 
	public ConsumerUsbDisk(ResourceFileRunnable rf) {
		this.rf = rf;
	}
 
	@Override
	public void run() {
		while (true) {
			rf.consumeFile();//消费
			try {
				Thread.sleep(1000);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
	}
 
}
ResourceFileRunnable 类
class ResourceFileRunnable {
    private static final Logger logger = LoggerFactory.getLogger(ResourceFileRunnable.class);
    private static final String MEDIA_PATH = "media/";
    private static final String PLAN_JSON_NAME = "planplaylist.json";

    private int count = 0; //判断是否有设备插入的标记
    private boolean flag = false;
    private File[] dirs;

    public ResourceFileRunnable(int count) {
        this.count = count;
    }

    //获取所有文件名
    public static void getAllFiles(File dir) throws Exception {
        File[] files = dir.listFiles();
        if (files != null) {
            for (File f : files) {
                if (f.isDirectory() && "rt".equalsIgnoreCase(f.getName())) {
                    File[] rtFiles = f.listFiles();
                    for(File rtF : rtFiles) {
                        if("playlist.json".equalsIgnoreCase(rtF.getName())) {
                            cpFile(rtF.getAbsolutePath(),PLAN_JSON_NAME);
                        }
                        if(rtF.isDirectory()) {
                            File[] subFiles = rtF.listFiles();
                            for(File subF : subFiles) {
                                if(subF.isDirectory()) {
                                    File[] sub2Files = subF.listFiles();
                                    for(File sub2F : sub2Files) {
                                        cpFile(subF.getAbsolutePath(), MEDIA_PATH + rtF.getName()
                                                + "/" + subF.getName() + "/" + sub2F.getName());
                                    }
                                } else {
                                    cpFile(subF.getAbsolutePath(), MEDIA_PATH + rtF.getName() + "/" + subF.getName());
                                }
                            }
                        } else {
                            cpFile(rtF.getAbsolutePath(),MEDIA_PATH + rtF.getName());
                        }
                    }

                    String planStr = FileUtils.readFile(PLAN_JSON_NAME);
                    RtPlan plan = JSON.parseObject(planStr, RtPlan.class);
                    NettyClient.getInstance().planReceived(plan);
                }
            }
        }
    }

    //查找资源--生产者使用
    public synchronized void searchFile() {
        if (flag) {
            try {
                wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }

        dirs = File.listRoots();
        if (dirs.length != count) {
            flag = true;
            notify();//唤醒消费者
        }
    }

    //消费资源--消费者使用
    public synchronized void consumeFile() {
        if (!flag) {
            try {
                wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        if (dirs.length > count) {
            try {
                getAllFiles(dirs[dirs.length - 1]);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }

        count = dirs.length;
        flag = false;
        notify();
    }

    private static void cpFile(String srcPath, String targetPath) {
        long start = System.currentTimeMillis();
        try {
            //源文件
            File src = new File(srcPath);
            //目标文件
            File desc = new File(targetPath);
            File descDir = desc.getParentFile();
            if(descDir != null && !descDir.exists()) {
                descDir.mkdirs();
            }
            FileInputStream fis = new FileInputStream(src);
            FileOutputStream fos = new FileOutputStream(desc);

            byte[] b = new byte[1024 * 1024];
            int len = -1;
            while ((len = fis.read(b)) != -1) {
                fos.write(b, 0, len);
                fos.flush();
            }
            fos.close();
            fis.close();
        } catch (IOException e) {
            e.printStackTrace();
        }

        long end = System.currentTimeMillis();
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值