java如何几乎同时结束两个线程

发布于 2022-09-12 12:53:18 字数 3577 浏览 47 评论 0

今天写了一个让文字何背景音乐几乎同时开始几乎同时结束的小程序,但是遇到了一个问题,就是如何同时结束两个线程的问题

我想到的第一种方式,因为只有两个线程可以直接终止;

       System.exit(0);

第二种方式; 如果不能正常开启音乐播放t线程t线程就结束了,使用静态属性,打boolean的方式,终止音乐播放程序但是没有办法立即停止

while (flag) { //没有办法立即停止;
 try {
        //将音乐文件放到play;
 Player player = new Player(new FileInputStream((new File(path))));
 player.play(); //播放音乐;
 } catch (JavaLayerException e) {
        e.printStackTrace();
 } catch (FileNotFoundException e) {
        e.printStackTrace();
 }
}

以下为源码

读取文件


import java.awt.*;
import java.awt.datatransfer.StringSelection;
import java.awt.event.KeyEvent;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.util.Random;
/*
 * runtime 类构造方法私有;--->单例模式;
 * * */public class showLove {
    public static boolean falg=true;
 public static void main(String[] args) throws IOException {
// 使用了单例模式; 使用Runtime 中自带的exec 方法,以command 命令的方式打开window下的程序


 Runtime  rt=Runtime.getRuntime();
 rt.exec("notepad");
 Thread t=new Thread( ()->{
            Musicutil.play("C:Users86152Musicやなぎなぎ - ユキトキ (雪融) (TV Size).mp3");
// 单线程要一行一行的执行,所以如果为单线程,就会播放音乐完成后再播放音乐;
  
 });
 t.start(); //开启音乐线程;
 try {
            Thread.sleep(2000);
 } catch (InterruptedException e) {
            e.printStackTrace();
 }
// 读取文件;
 readFile("C:Users86152Desktopjava练习content.txt");
// 强行终止进程以达到结束两个线程的;
 }
// 判断主线程是否执行完毕;
 public static boolean judgeOfThread(){
        return true;
 }
    /**
 * 读取文件
 * @param path //文件的路径
 */
 public static void readFile(String path){

// 自动关闭try with resources; JDK1.7新特性


 try( FileReader fr=new FileReader(path)){
            int c;
 while( (c=fr.read()) !=-1){
                //将读取的部分转化为字符串;
 copyAndPaste(String.valueOf((char) c));
 }
        } catch (FileNotFoundException e) {
            e.printStackTrace();
 } catch (IOException e) {
            e.printStackTrace();
 }
    }
    /**
 * 将数据粘贴到文件中;
 * @param str
 */
 public static void copyAndPaste(String str){
        //创建StringSelection对象,将str() 放入;
 
 StringSelection  stringSelection=new StringSelection(str);
 
 Toolkit.getDefaultToolkit().getSystemClipboard().setContents(stringSelection,stringSelection);
//       ctrl V;---.模拟ctrl v 的执行;

 Robot robot=null;
 try {
            robot = new Robot();
 } catch (AWTException e) {
            e.printStackTrace();
 }
// 两个键的按下;
 robot.keyPress(KeyEvent.VK_CONTROL);
 robot.keyPress(KeyEvent.VK_V);
//键盘的松开;
 robot.keyRelease(KeyEvent.VK_V);
 robot.keyRelease(KeyEvent.VK_CONTROL);
// 随机的delay() 延迟;
 Random random=new Random();
 int delay= random.nextInt(600); //随机数的边界
 if(delay<100){
            delay+=200;
 }
        robot.delay(delay); //单位为毫秒;
 }
}

播放音乐 ,使用了外接jar包


import javazoom.jl.decoder.JavaLayerException;
import javazoom.jl.player.Player;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
/**
 * 播放音乐
 * */
public class Musicutil{
    public static void play(String path) {
//player是一个流对象;
 while (true) { //没有办法立即停止;
 try {
                //将音乐文件放到play;
 Player player = new Player(new FileInputStream((new File(path))));
 player.play(); //播放音乐;
 } catch (JavaLayerException e) {
                e.printStackTrace();
 } catch (FileNotFoundException e) {
                e.printStackTrace();
 }
        }
    }
}

想问问有更好的解决方案吗 .interrput() 方法在这好像不好使用,希望大神们给我提出更好的解决方案;

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

坚持沉默 2022-09-19 12:53:18

第1个线程:播放音乐
第2个线程:输出文字
在第二个线程中输出文字前判断第一个线程是否还在运行,如果在运行再输出文字

扭转时空 2022-09-19 12:53:18

用观察者比较清晰。
定义一个被观察者player,把播放和文字显示等操作注册为观察者,当播放时(或者异常、退出等),操作player对象,自动通知播放和文字等一些列操作做出响应。例如:播放、歌词、歌手图、动态评论等

2022-09-19 12:53:18

还有一个损招:拔掉电源

抠脚大汉 2022-09-19 12:53:18

从理论上来说,线程无法被强制中断,但是可以响应中断,就是通过interrput标记 来响应中断,默认可以中断sleep阻塞。你应该在线程中多次查看interrput 标记,如果有标记,就中止服务。如果是使用executors,直接调用shutdownNow()就是打上了中断标记,如果要优雅的关闭线程还需要捕获interrputedException异常,做好后续处理。如果要处理io阻塞,等待阻塞等,则需要使用相对应的并发编程类。

夜光 2022-09-19 12:53:18

可以用线程池来控制,示例代码如下:

// 创建一个线程池,大小为2
ExecutorService es = Executors.newFixedThreadPool(2);
es.execute(new Player());
es.execute(new ReadText());
// 结束时调用线程池的shutdownNow,线程池将立刻马上终止所有线程,终止时间大概是同时的
es.shutdownNow();

至于同时启动就简单多了,用wait+notify、CyclicBarrier或Semaphore都可以达到目的。

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文