zoukankan      html  css  js  c++  java
  • JAVA 多线程(2)

    一、首先 Thread 是实现了Runable 接口的类

    理论上Thread 实例与直接实现runable接口的实例运行起来没有什么不同,但是由于JAVA 是单继承,所以如果想再一个类中实现2个不同的thread只有通过实现runable接口。

    再来看Thread中start 和 run 的不同,start是启动线程或者说在准备好的thread线程下告诉JVM 准备就绪,可以执行这个线程了,是异步的,也就是说,在启动线程的宿主类中的代码,

    并不是按照顺序来执行的。

    run方法是立即执行,则不再依附在创建的线程中,而是在主线程中的执行,例如:

    public static void main(String[] args){
    
            Thread t = new Thread(new Runnable() {
                @Override
                public void run() {
                    System.out.println(Thread.currentThread().getName());
                }
            });
            t.setName("我是Thread子线程");
    
            t.start();
    
            t.run();
    
            System.out.println(Thread.currentThread().getName()+": 我在main下");
        }
    

     输出结果:

     首先线程 给线程t起了一个名字叫 “我是Thread子线程”,代码中是先 start 然后 run ,最后在主线程main中打印(main 并不是方法名main(),main代表的是主线程)

    控制台输出接口可以看出,首先代码的顺序跟真正的执行顺序不一致,然后run方法直接打印了主线程的名字 main,因为run方法会在当前执行线程下直接执行,

    然后因为给t线程重命名了线程名,所有在start方法调用时,当t线程准备就绪后通知JVM 它已经准备好了,可以调用cpu资源了,当它抢到后才开始执行run方法中的事件。

    二、关于守护线程

    守护线程与用户线程的概念,可以去网上搜一下,这里我只是稍微说一下个人理解。

    可以这样理解在一个进程中有多个线程同时存在,其中分为守护线程与用户线程,理论上所有我们自己执行的事件都属于用户线程,守护线程相当于助理或者说保姆,

    比方说,总经理(用户线程)有一个助理(守护线程),如果总经理的工作结束了,那么助理的工作也相当于结束了(例子不是很恰当,理解就好)。

    守护线程最典型的就是GC垃圾回收。

    当然我们也可以把用户线程变为守护线程

    t.setDaemon(true);
    

     他回依附于用户线程,当非守护线程都结束工作或停止后,它业就停止了。

    三、停止线程

    停止线程有stop、suspend、interrupt,前面2个方法已经废弃了,有兴趣的可以去网上搜下。

    interrupt 并不是真正意义上的停止,而是加上一个停止标记。

    判断线程是否停止有2个方法

    interrupted 和 isInterrupted。

    前者是静态方法。

    区别:

    interrupted 方法会修改停止标记,比如连续调用2次的话,会把true改回false(true 停止了,false激活了)

    isInterrupted不会,它只是获得这个是否停止标记。

    实际停止正在运行的线程可以通过异常法,例如:

    throw new InterruptedException()
    

     然后catch捕捉,处理后续事件。

    sleep 沉睡:

    在沉睡中停止线程有可能会出现2中情况,在于调用sleep函数的位置,如果是在主线程中操作,有可能start准备好后,在run方法为执行的情况下就终止了线程。

    getId:获取线程的id

    四、优先级

    关于线程优先级,其分为10个等级,如果在调用setPriority 设置优先级的时候,不再这个范围内,会抛出异常。

    另外设置优先级,针对jvm 并不一定会按照设置的优先级去执行,只是说优先级高的线程,有可能会比其他优先级较低的线程多一些可能性。

    另外优先级具有继承特性,A线程被B线程继承,如果设置A线程的优先级为8,那么B线程的优先级也会更改为8。

    五、放弃CPU资源

    yield 方法是放弃当前的CPU资源,然后回到争资源的行列。

    比如做公车让座,假设只有1个座位,现在是年轻人作者(线程A),上来一个老年人(线程C),年轻人起身让座给老年人,这是还有人D,人E...等人都是站着的,

    假设除了老人到站了,起身下车,那么这个座位又空了,这时候就看谁能抢到这个座位了(cpu资源),有可能还是让座的那个年轻人(线程A),也可能是线程D、E。。。。

    所有说,yield方法是暂时放弃了资源,但是又可能刚放弃又重启获得了这个资源都是有可能的。

    成灰之前,抓紧时间做点事!!
  • 相关阅读:
    Atitit RSA非对称加密原理与解决方案
    Atitit RSA非对称加密原理与解决方案
    atitit.错误:找不到或无法加载主类 的解决 v4 qa15.doc
    atitit.错误:找不到或无法加载主类 的解决 v4 qa15.doc
    Mac设置su root密码
    Window系统命令行调用控制面板程序
    Ubuntu 安装最新版nodejs
    python中time.strftime不支持中文,报错UnicodeEncodeError: 'locale' codec can't encode character 'u5e74' in position 2: encoding error
    字节跳动——IT技术工程师面试题
    HTTP状态码
  • 原文地址:https://www.cnblogs.com/jony-it/p/10769176.html
Copyright © 2011-2022 走看看