zoukankan      html  css  js  c++  java
  • java多线程

    1.进程和线程的区别:

        每个正在系统上运行的程序都是一个进程。每个进程包含一到多个线程。线程是一组指令的集合,或者是程序的特殊段,它可以在程序里独立执行。也可以把它理解为代码运行的上下文。所以线程基本上是轻量级的进程,它负责在单个程序里执行多任务。通常由操作系统负责多个线程的调度和执行。

       总结:进程是所有线程的集合,每一个线程是进程中的一条执行路径。

    2.为什么要使用多线程

     案例:如果一个工人修建一条1000米长的铁路需要10个小时,为了尽快完成工期,需要在一个小时内完成所有的铁路修建,如何解决呢?

    此时可以在加派9个工人,最后就是10个工人一起修建(考虑每个工人的修建速度一样)则只需要1个小时就可以完成.

    同样:使用多线程可以提高程序的效率.

    3.在java中如何创建多线程

      1.继承Thread类,重写run方法

    package com.thread;
    
    public class ThreadDemo extends Thread {
        @Override
        public void run() {
            System.out.println("继承Thread重写run方法");
        }
    
        public static void main(String[] args) {
            ThreadDemo threadDemo = new ThreadDemo();
            threadDemo.start();
        }
    }
    输出:继承Thread重写run方法

    注意:启动一个线程是用的.start()方法 而不是直接调用的run方法,如果直接调用run方法只是实例化的一个方法调用,根本没有启动一个线程

    思考:开启一个线程以后,该线程和main方法的执行先后顺序?

     

    package com.thread;
    
    public class ThreadDemo extends Thread {
        @Override
        public void run() {
            System.out.println("继承Thread重写run方法");
        }
    
        public static void main(String[] args) {
            System.out.println("main方法开始运行");
            ThreadDemo threadDemo = new ThreadDemo();
            threadDemo.start();
            System.out.println("main方法结束");
        }
    }

    输出结果:

    main方法开始运行
    main方法结束
    继承Thread重写run方法

    从输出结果可以看出,主程序的运行结束与否和新创建的线程运行情况无关,即使主线程运行完成,此时可能用户线程还在运行,不会随着主线程消亡而结束(守护线程则会)

     2.实现Runnable接口的方法

      

    package com.thread;
    
    public class RunnableDemo implements Runnable {
        public void run() {
            System.out.println("实现Runnable接口重写run方法");
        }
    
        public static void main(String[] args) {
            RunnableDemo runnableDemo = new RunnableDemo();
            Thread thread = new Thread(runnableDemo);
            thread.start();
        }
    }

    输出结果:

    实现Runnable接口重写run方法

     3.使用匿名内部类的方法创建多线程

     public static void main(String[] args) {
            new Thread(new Runnable() {
                public void run() {
                    System.out.println("匿名内部类的方法创建线程运行run方法");
                }
            }).start();
    
        }

    4.使用Callabel接口创建一个具有返回值的线程

    package com.thread;
    
    import java.util.concurrent.Callable;
    import java.util.concurrent.ExecutionException;
    import java.util.concurrent.FutureTask;
    
    public class CallableThreadDemo implements Callable<String> {
        public static void main(String[] args) throws ExecutionException, InterruptedException {
            CallableThreadDemo callableThreadDemo = new CallableThreadDemo();
            FutureTask<Integer> futureTask = new FutureTask(callableThreadDemo);
            new Thread(futureTask, "有返回值的线程").start();
            System.out.println(futureTask.get());
        }
    
        public String call() throws Exception {
            return "我是线程 Callable接口的返回值哟";
        }
    
    
    }

    输出结果:

    我是线程 Callable接口的返回值哟

    5.使用线程池创建线程(后续补充)

    4. 在创建线程的时候使用Thread继承好还是使用Runnable接口好

    答:使用接口好,接口可以多继承

     

    5.常用的线程API

      1.获取当前线程对象的方法:currentThread()

      2.启动线程:.start()

      3.休眠线程:sleep(时间)cpu执行其他线程,但是不会释放当前线程已经拥有的锁

      4.停止线程:stop()

    6.线程的分类

     线程分成两类

      1.用户自定义线程:该线程不会随着主线程死亡而死亡,可以理解成main方法执行完毕以后,自定义线程还在执行

      2.守护线程:主线程执行完毕以后守护线程就自动死亡,可以通过thread.setDaemon(true)将该线程设置为守护线程

    7.线程的状态(重点)

      1.新建状态:new Thread()表示一个线程的创建,但是此时线程还并没有开始执行

     2.就绪状态:当前线程调用start()的时候 表示线程已经就绪,此时等待cpu调度

     3.运行状态:如果当前线程获取到了cpu的执行权,则开始运行该程序(执行run方法)

     4.死亡状态:run方法正常的执行完毕,或者run方法里面执行错误,该错误没有被捕获也会导致线程死亡(和main方法一样如果程序出错,没有捕获异常,则程序不会继续执行)

     5.阻塞状态:导致线程阻塞的情况有很多场景:比如调用sleep()方法,在同步锁当中执行一个方法的时候,没有获取到该方法的锁也会阻塞。如果操作数据库的时候IO时间较长,该线程也会阻塞  在调用sleep()方法以后,休眠时间到了,重新获取到cpu的执行权,则该线程又进入到运行状态

    8.设置线程的优先级和如何让多个线程优先执行一个线程

     优先级:现代操作系统基本采用时分的形式调度运行的线程,线程分配得到的时间片的多少决定了线程使用处理器资源的多少,也对应了线程优先级这个概念。在JAVA线程中,通过一个int priority来控制优先级,范围为1-10,其中10最高,默认值为5。可以通过 Thread.setPriority设置线程的优先级,设置优先级并不是每次都执行这个线程,只是会优先于这个线程

     顺序性:如果有三个线程,你先让线程2先执行,执行完成以后 在执行线程1,最后在执行线程3 使用join

     

    package com.thread;
    
    public class ThreadDemo extends Thread {
        @Override
        public void run() {
            String name = currentThread().getName();
            System.out.println(name + "继承Thread重写run方法");
        }
    
        public static void main(String[] args) throws InterruptedException {
            ThreadDemo threadDemo1 = new ThreadDemo();
            threadDemo1.setName("线程1");
            ThreadDemo threadDemo2 = new ThreadDemo();
            threadDemo2.setName("线程2");
            ThreadDemo threadDemo3 = new ThreadDemo();
            threadDemo3.setName("线程3");
            threadDemo2.start();
            threadDemo2.join();
            threadDemo1.start();
            threadDemo1.join();
            threadDemo3.start();
    
        }
    }

    输出结果:

    线程2继承Thread重写run方法
    线程1继承Thread重写run方法
    线程3继承Thread重写run方法

     

  • 相关阅读:
    SQL常用单词
    Appium+python自动化获取toast消息的方法
    转:TCP/IP协议(一)网络基础知识
    【转】使用python实现appium的屏幕滑动
    JMETER java.net.SocketTimeoutException: Read timed out
    JMETER java.net.SocketException: Connection reset 报错解决方案
    Jmeter Distributed (Remote) Testing: Master Slave Configuration
    转:Jmeter分布式测试
    转:centos查看实时网络带宽占用情况方法
    Python类继承(转发)
  • 原文地址:https://www.cnblogs.com/920913cheng/p/11340597.html
Copyright © 2011-2022 走看看