• 多线程


    * 进程:
    * 正在运行的程序,是系统进行资源分配和调用的独立单位。
    * 每一个进程都有它自己的内存空间和系统资源。
    * 线程:
    * 是进程中的单个顺序控制流,是一条执行路径
    * 一个进程如果只有一条执行路径,则称为单线程程序。
    * 一个进程如果有多条执行路径,则称为多线程程序。


    * 大家注意两个词汇的区别:并行和并发。
    * 前者是逻辑上同时发生,指在某一个时间内同时运行多个程序。
    * 后者是物理上同时发生,指在某一个时间点同时运行多个程序。
    *
    * Java程序的运行原理:
    * 由java命令启动JVM,JVM启动就相当于启动了一个进程。
    * 接着有该进程创建了一个主线程去调用main方法。

    * 思考题:
    * jvm虚拟机的启动是单线程的还是多线程的?
    * 多线程的。
    * 原因是垃圾回收线程也要先启动,否则很容易会出现内存溢出。
    * 现在的垃圾回收线程加上前面的主线程,最低启动了两个线程,所以,jvm的启动其实是多线程的。

    * 方式1:继承Thread类。
    * 步骤
    * A:自定义类MyThread继承Thread类。
    * B:MyThread类里面重写run()?
    * 为什么是run()方法呢?
    * C:创建对象
    * D:启动线程

    /*
     * 该类要重写run()方法,为什么呢?
     * 不是类中的所有代码都需要被线程执行的。
     * 而这个时候,为了区分哪些代码能够被线程执行,java提供了Thread类中的run()用来包含那些被线程执行的代码。
     */
    public class MyThread extends Thread {
    
        @Override
        public void run() {
            // 自己写代码
            // System.out.println("好好学习,天天向上");
            // 一般来说,被线程执行的代码肯定是比较耗时的。所以我们用循环改进
            for (int x = 0; x < 200; x++) {
                System.out.println(x);
            }
        }
    }

    // 调用run()方法为什么是单线程的呢?
    // 因为run()方法直接调用其实就相当于普通的方法调用,所以你看到的是单线程的效果
    // 要想看到多线程的效果,就必须说说另一个方法:start()
    // 面试题:run()和start()的区别?
    // run():仅仅是封装被线程执行的代码,直接调用是普通方法
    // start():首先启动了线程,然后再由jvm去调用该线程的run()方法。

    // MyThread my = new MyThread();
    // my.start();
    // // IllegalThreadStateException:非法的线程状态异常
    // // 为什么呢?因为这个相当于是my线程被调用了两次。而不是两个线程启动。
    // my.start();

    // 创建两个线程对象
            MyThread my1 = new MyThread();
            MyThread my2 = new MyThread();
    
            my1.start();
            my2.start();

    * 如何获取线程对象的名称呢?
    * public final String getName():获取线程的名称。
    * 如何设置线程对象的名称呢?
    * public final void setName(String name):设置线程的名称

    * 针对不是Thread类的子类中如何获取线程对象名称呢?
    * public static Thread currentThread():返回当前正在执行的线程对象
    * Thread.currentThread().getName()

    方法一:

    // 创建线程对象
            //无参构造+setXxx()
             MyThread my1 = new MyThread();
             MyThread my2 = new MyThread();
            // //调用方法设置名称
             my1.setName("林青霞");
             my2.setName("刘意");
             my1.start();
             my2.start();

    方法二:

    //带参构造方法给线程起名字
             MyThread my1 = new MyThread("林青霞");
             MyThread my2 = new MyThread("刘意");
             my1.start();
             my2.start();
    
            //我要获取main方法所在的线程对象的名称,该怎么办呢?
            //遇到这种情况,Thread类提供了一个很好玩的方法:
            //public static Thread currentThread():返回当前正在执行的线程对象
            System.out.println(Thread.currentThread().getName());
    public class MyThread extends Thread {
    
        public MyThread() {
        }
    
        public MyThread(String name){
            super(name);
        }
    
        @Override
        public void run() {
            for (int x = 0; x < 100; x++) {
                System.out.println(getName() + ":" + x);
            }
        }
    }

    * 我们的线程没有设置优先级,肯定有默认优先级。
    * 那么,默认优先级是多少呢?
    * 如何获取线程对象的优先级?
    * public final int getPriority():返回线程对象的优先级
    * 如何设置线程对象的优先级呢?
    * public final void setPriority(int newPriority):更改线程的优先级。 

    * 注意:
    * 线程默认优先级是5。
    * 线程优先级的范围是:1-10。
    * 线程优先级高仅仅表示线程获取的 CPU时间片的几率高,但是要在次数比较多,或者多次运行的时候才能看到比较好的效果。

    * IllegalArgumentException:非法参数异常。
    * 抛出的异常表明向方法传递了一个不合法或不正确的参数。

    ThreadPriority tp1 = new ThreadPriority();
            ThreadPriority tp2 = new ThreadPriority();
            ThreadPriority tp3 = new ThreadPriority();
    
            tp1.setName("东方不败");
            tp2.setName("岳不群");
            tp3.setName("林平之");
    
            // 获取默认优先级
            // System.out.println(tp1.getPriority());
            // System.out.println(tp2.getPriority());
            // System.out.println(tp3.getPriority());
    
            // 设置线程优先级
            // tp1.setPriority(100000);
    
            //设置正确的线程优先级
            tp1.setPriority(10);
            tp2.setPriority(1);
    
            tp1.start();
            tp2.start();
            tp3.start();

    * 线程休眠
    * public static void sleep(long millis)

     * public final void join():等待该线程终止。 

    等线程tj1执行完毕才执行其他线程

    ThreadJoin tj1 = new ThreadJoin();
            ThreadJoin tj2 = new ThreadJoin();
            ThreadJoin tj3 = new ThreadJoin();
    
            tj1.setName("李渊");
            tj2.setName("李世民");
            tj3.setName("李元霸");
    
            tj1.start();
            try {
                tj1.join();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
    
            tj2.start();
            tj3.start();

    * public static void yield():暂停当前正在执行的线程对象,并执行其他线程。 
    * 让多个线程的执行更和谐,但是不能靠它保证一人一次。

    * public final void setDaemon(boolean on):将该线程标记为守护线程或用户线程。
    * 当正在运行的线程都是守护线程时,Java 虚拟机退出。 该方法必须在启动线程前调用。

    public static void main(String[] args) {
            ThreadDaemon td1 = new ThreadDaemon();
            ThreadDaemon td2 = new ThreadDaemon();
    
            td1.setName("关羽");
            td2.setName("张飞");
    
            // 设置收获线程
            td1.setDaemon(true);
            td2.setDaemon(true);
    
            td1.start();
            td2.start();
    
            Thread.currentThread().setName("刘备");
            for (int x = 0; x < 5; x++) {
                System.out.println(Thread.currentThread().getName() + ":" + x);
            }
        }

    * public final void stop():让线程停止,过时了,但是还可以使用。
    * public void interrupt():中断线程。 把线程的状态终止,并抛出一个InterruptedException。

    更多技术来源:https://www.cnblogs.com/samuraihuang/p/10041319.html

    -------------------------------------------------------------------------------------感谢到访!期待您的下次光临!

  • 相关阅读:
    p4841 城市规划
    p2619 [国家集训队2]Tree I [wqs二分学习]
    p3723 [AH2017/HNOI2017]礼物
    p5437 【XR-2】约定
    p5349 幂
    数据结构:结构之美
    你所不知道的传输层
    为什么选择这种技术而不选择另一种技术?
    Internet路由-主机路由表和转发表
    计算机网络----数据链路层(三)
  • 原文地址:https://www.cnblogs.com/varchar-pig/p/14249588.html
Copyright © 2020-2023  润新知