JAVA线程杂谈记录

举报
赵KK日常技术记录 发表于 2023/06/24 13:57:47 2023/06/24
【摘要】 本来前天就更的,后来删掉了,思前想后觉得不合适,毕竟是别人的辛苦原创,在得到本人允许的情况,根据视频,整理资料,虽然是私人公众号,但有可能因此获益,还是需要标明出处,另外周五实在太晚,第二天还要加班,后期敲的也不是特别多,重新发布。 写在前面:see see easy do do hard,不要觉得你写两天CRUD就窥的技术真理了,技术远不紧如此。 首先说下近期更新的问题,我的...

本来前天就更的,后来删掉了,思前想后觉得不合适,毕竟是别人的辛苦原创,在得到本人允许的情况,根据视频,整理资料,虽然是私人公众号,但有可能因此获益,还是需要标明出处,另外周五实在太晚,第二天还要加班,后期敲的也不是特别多,重新发布。

    写在前面:see see easy  do do hard,不要觉得你写两天CRUD就窥的技术真理了,技术远不紧如此。

    首先说下近期更新的问题,我的初衷是通过公众号的方式,记录下日常遇到的问题或者记录得到的知识,但近期实在是素材少,没有一个能够全品穿插的知识点,很难能全篇讲下来,然后最近都是加班状态,也没有时间去看资料,去写东西,今天实在是觉得很久没更新,竟然有点亏欠的感觉。

    那么前几天朋友推荐了个视频,里面的内容全部都是干货,全都是进阶的知识点,对源码,框架,都有很大的帮助,借此机会整理下以前的知识点。

    主要是关于线程方面的,怎么说呢(giao),线程操作无疑是衡量一段代码的质量标准,很多基础,或者很多资料其实也都是一传十,百Ctrl +C Ctrl+V,时间一久,很难分辨,这里就突出了源码的重要性。

    以前也整理过3篇关于线程线程池的文章,有些东西就是仁者见仁智者见智,存在即合理吧,但还是需要更严谨的去看待问题。

正文:

    从问题入手

   1.创建线程有几种方式?

   这个问题就答案很多,多到能搜到8种的都有,个人认为还是要答JDK1.5以前1:继承Thread类,实现Runable接口,JDK1.5以后新增2:实现Callable接口,线程池中获得。

    但换一种问法,java中如何创建一个线程?


    表面上看没什么啊?这不都一样么?但更严谨的说法是看源码

请在此添加图片描述

//2019年9月27日23:56:31 KK:Lambda判断是否是函数型接口
@FunctionalInterface
public interface Runnable {
    /**
     * When an object implementing interface <code>Runnable</code> is used
     * to create a thread, starting the thread causes the object's
     * <code>run</code> method to be called in that separately executing
     * thread.
     * <p>
     * The general contract of the method <code>run</code> is that it may
     * take any action whatsoever.
     *
     * @see     java.lang.Thread#run()
     */
    public abstract void run();
}

源码中表示:There are two ways to create a new thread of execution.一个是new Thread(),一个是实现Runable()接口

2.如何创建一个进程?

Runtime runtime = Runtime.getRuntime();
        Process process = runtime.exec("cmd /k start www.baidu.com");
        process.exitValue();

java无法销毁一个线程,只能改变线程状态,thread.Alive() 返回false时已经被销毁

3.如何启动线程?


 thread.start()


4.如何制定线程的执行顺序

正常肯定是CountDownLatch(),Semaphore等方法可以实现,或者可以指定线程等待,唤醒另一个线程,但其实首先应该想到的是join方法

先看下t1.start,t2.start,t3.start执行顺序

第一次

请在此添加图片描述

第二次

请在此添加图片描述

可以看到,多线程环境下,执行顺序与书写顺序每次都不一定相同

解决方案:

方法一:join

public class HelloWorld {
    public static void main(String[] args) throws InterruptedException, IOException {
        Thread t1 = new Thread(HelloWorld::action, "t1");
        Thread t2 = new Thread(HelloWorld::action, "t2");
        Thread t3 = new Thread(HelloWorld::action, "t3");
        t1.start();
        t1.join();
        t2.start();
        t2.join();
        t3.start();
        t3.join();
    }
    public static void action(){
        System.out.println("线程"+Thread.currentThread().getName()+"执行");
    }
}
结果:
D:\ProgramFiles\JavaTest\java\jdk1.8.0_141\bin\java.exe "-javaagent:D:\idea\IntelliJ IDEA 2019.1.1\lib\idea_rt.jar=59503:D:\idea\IntelliJ IDEA 2019.1.1\bin" -Dfile.encoding=UTF-8 -classpath D:\ProgramFiles\JavaTest\java\jdk1.8.0_141\jre\lib\charsets.jar;D:\ProgramFiles\JavaTest\java\jdk1.8.0_141\jre\lib\deploy.jar;D:\ProgramFiles\JavaTest\java\jdk1.8.0_141\jre\lib\ext\access-bridge-64.jar;D:\ProgramFiles\JavaTest\java\jdk1.8.0_141\jre\lib\ext\cldrdata.jar;D:\ProgramFiles\JavaTest\java\jdk1.8.0_141\jre\lib\ext\dnsns.jar;D:\ProgramFiles\JavaTest\java\jdk1.8.0_141\jre\lib\ext\jaccess.jar;D:\ProgramFiles\JavaTest\java\jdk1.8.0_141\jre\lib\ext\jfxrt.jar;D:\ProgramFiles\JavaTest\java\jdk1.8.0_141\jre\lib\ext\localedata.jar;D:\ProgramFiles\JavaTest\java\jdk1.8.0_141\jre\lib\ext\nashorn.jar;D:\ProgramFiles\JavaTest\java\jdk1.8.0_141\jre\lib\ext\sunec.jar;D:\ProgramFiles\JavaTest\java\jdk1.8.0_141\jre\lib\ext\sunjce_provider.jar;D:\ProgramFiles\JavaTest\java\jdk1.8.0_141\jre\lib\ext\sunmscapi.jar;D:\ProgramFiles\JavaTest\java\jdk1.8.0_141\jre\lib\ext\sunpkcs11.jar;D:\ProgramFiles\JavaTest\java\jdk1.8.0_141\jre\lib\ext\zipfs.jar;D:\ProgramFiles\JavaTest\java\jdk1.8.0_141\jre\lib\javaws.jar;D:\ProgramFiles\JavaTest\java\jdk1.8.0_141\jre\lib\jce.jar;D:\ProgramFiles\JavaTest\java\jdk1.8.0_141\jre\lib\jfr.jar;D:\ProgramFiles\JavaTest\java\jdk1.8.0_141\jre\lib\jfxswt.jar;D:\ProgramFiles\JavaTest\java\jdk1.8.0_141\jre\lib\jsse.jar;D:\ProgramFiles\JavaTest\java\jdk1.8.0_141\jre\lib\management-agent.jar;D:\ProgramFiles\JavaTest\java\jdk1.8.0_141\jre\lib\plugin.jar;D:\ProgramFiles\JavaTest\java\jdk1.8.0_141\jre\lib\resources.jar;D:\ProgramFiles\JavaTest\java\jdk1.8.0_141\jre\lib\rt.jar;D:\project01\target\classes com.kk.HelloWorld
线程t1执行
线程t2执行
线程t3执行
Process finished with exit code 0

方法二:自旋

public class HelloWorld {
    public static void main(String[] args) throws InterruptedException, IOException {
        Thread t1 = new Thread(HelloWorld::action, "t1");
        Thread t2 = new Thread(HelloWorld::action, "t2");
        Thread t3 = new Thread(HelloWorld::action, "t3");
        t1.start();
        while (t1.isAlive()) {

        }
        t2.start();
        while (t2.isAlive()) {

        }
        t3.start();
        while (t3.isAlive()) {

        }
    }
    public static void action() {
        System.out.println("线程" + Thread.currentThread().getName() + "执行");

    }
}
结果一样

方法三自旋基础加上睡眠

public class HelloWorld {
    public static void main(String[] args) throws InterruptedException, IOException {
        Thread t1 = new Thread(HelloWorld::action, "t1");
        Thread t2 = new Thread(HelloWorld::action, "t2");
        Thread t3 = new Thread(HelloWorld::action, "t3");
        t1.start();
        while (t1.isAlive()) {
            Thread.sleep(0);
        }
        t2.start();
        while (t2.isAlive()) {
            Thread.sleep(0);
        }
        t3.start();
        while (t3.isAlive()) {
            Thread.sleep(0);
        }
    }

    public static void action() {
        System.out.println("线程" + Thread.currentThread().getName() + "执行");

    }
}方法四 wait
public class HelloWorld {
    public static void main(String[] args) throws InterruptedException, IOException {
        Thread t1 = new Thread(HelloWorld::action, "t1");
        Thread t2 = new Thread(HelloWorld::action, "t2");
        Thread t3 = new Thread(HelloWorld::action, "t3");
        //tsleep(t1, t2, t3);
        threadWait(t1);
        threadWait(t2);
        threadWait(t3);
    }

    private static void threadWait(Thread thread) {
        if (Thread.State.NEW.equals(thread.getState())) {
            thread.start();
        }
        while (thread.isAlive()) {
            synchronized (thread) {
                try {
                    thread.wait();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }

        }
    }

这个自旋的while和CAS那个自旋异曲同工

5.如何终止一个线程?

这个问题昨天还遇到了,定时任务时监控状态,成功后终止监控

Thread interrupt()

interrupted 的区别和含义

Thread interrupt() 设置状态

isInterrupted() 判断 返回Boolean

interrupted 即判断又清除稿定设计网页你怎么了?

请在此添加图片描述

2019年9月28日00:26:33 休息了…

【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。