zoukankan      html  css  js  c++  java
  • 多线程学习:线程基础

    线程的基本概念

    进程与线程

    • 进程
      进程是程序的一次执行过程,是系统运行程序的基本单位,因此进程是动态的。系统运行一个程序即是一个进程从创建,运行到消亡的过程。
      在 Java 中,当我们启动 main 函数时其实就是启动了一个 JVM 的进程,而 main 函数所在的线程就是这个进程中的一个线程,也称主线程。
    • 线程
      线程与进程相似,但线程是一个比进程更小的执行单位。一个进程在其执行的过程中可以产生多个线程。与进程不同的是同类的多个线程共享进程的方法区资源,但每个线程有自己的程序计数器虚拟机栈本地方法栈,所以系统在产生一个线程,或是在各个线程之间作切换工作时,负担要比进程小得多,也正因为如此,线程也被称为轻量级进程。

    并发与并行

    • 并发: 同一时间段,多个任务都在执行 (单位时间内不一定同时执行);
    • 并行:单位时间内,多个任务同时执行。

    线程的创建方式

    方法一:继承Thread类,作为线程对象存在(继承Thread对象)

    public class Test extends Thread {
        @Override
        public void run() {
           while (!interrupted()){
               System.out.println(Thread.currentThread().getName()+"执行了线程");
           }
        }
        public static void main(String[] args) {
            Test t=new Test();
            Test t1=new Test();
            t.start();
            t1.start();
            //中断第一个线程
            t.interrupt();
            }
    }
    

    方法二:实现runnable接口

    public class Test implements Runnable {
        @Override
        public void run() {
    
            System.out.println(Thread.currentThread().getName() + "执行了线程");
        }
        public static void main(String[] args) {
            Thread t = new Thread(new Test());
            t.start();
        }
    }
    

    使用匿名内部类方式 lambda和匿名内部来类似

       public static void main(String[] args) {
            new Thread(() -> System.out.println("执行了线程")).start();
        }
    

    方法三:创建带返回值的线程

    public class CreatThreadDemo4 implements Callable {
        public static void main(String[] args) throws ExecutionException, InterruptedException {
            CreatThreadDemo4 demo4 = new CreatThreadDemo4();
    
            FutureTask<Integer> task = new FutureTask<Integer>(demo4); //FutureTask最终实现的是runnable接口
    
            Thread thread = new Thread(task);
    
            thread.start();
    
            System.out.println("我可以在这里做点别的业务逻辑...因为FutureTask是提前完成任务");
            //拿出线程执行的返回值
            Integer result = task.get();
            System.out.println("线程中运算的结果为:"+result);
        }
    
        //重写Callable接口的call方法
        @Override
        public Object call() throws Exception {
            int result = 1;
            System.out.println("业务逻辑计算中...");
            Thread.sleep(3000);
            return result;
        }
    }
    

    线程的状态

    1. 就绪(Runnable):线程准备运行,不一定立马就能开始执行。
    2. 运行中(Running):进程正在执行线程的代码。
    3. 等待中(Waiting):线程处于阻塞的状态,等待外部的处理结束。
    4. 睡眠中(Sleeping):线程被强制睡眠。
    5. I/O阻塞(Blocked on I/O):等待I/O操作完成。
    6. 同步阻塞(Blocked on Synchronization):等待获取锁。
    7. 死亡(Dead):线程完成了执行。

    多线程的一些常用方法

    • start():启动线程
    • currentThread():获取当前线程兑现
    • getPriority() :获取当前线程的优先级
    • setPriority(int newPriority): 设置当前线程的优先级(1-10,1代表最低优先级,10代表最高优先级)
    • isAlive() :判断线程是否处于活动状态 (线程调用start后,即处于活动状态)
    • sleep(long millis):线程对象调用sleep(time)方法后,当前线程会等待指定的时间(time),并让出cpu执行权,但是它的监控状态依然当前对象的保持者(不会释放对象锁,休眠的线程会进入阻塞中泰中),当指定的时间到了又会自动恢复运行状态。
    • interrupt():interrupt()并不能中断在运行中的线程,它只能改变中断状态而已
    • interrupted:判断当前线程对象的状态是否为中断状态,内部实现是调用的当前线程的isInterrupted(),并且会重置当前线程的中断状态。
    • isInterrupted:判断当前线程对象的状态是否为中断状态,不会重置当前线程的中断状态
    • isDaemon( ) :判断是否为守护线程
    • setDaemon(boolean on):设置为守护线程
    • join():在A线程中调用了B线程的join()方法时,表示只有当B线程执行完毕时,A线程才能继续执行。并且join()方法是会释放锁的,因为底层使用 wait() 方法来实现的。
    • yield():放弃当前的CPU资源,将它让给其他的任务去占用CPU执行时间。但放弃的时间不确定,有可能刚刚放弃,马上又获得CPU时间片(不会释放锁)
    • wait() 使当前线程阻塞,直到调用notify(),则被唤醒。,wait(long timeOut)使当前线程阻塞,直到调用notify()或时长超过timeOut,则被唤醒。wait会释放锁
    • notify() / notifyAll():唤醒单个线程/唤醒所有线程
      wait()和notify()、notifyAll()方法的调用都必须在synchronized修饰的方法或者代码块中调用,使用过程中必须获得对象锁,否则会抛出java.lang.IllegalMonitorStateException的异常。
  • 相关阅读:
    3、MHC主要组织相容性复合体
    2、抗原
    1、免疫细胞
    【转】python3 内循环中遍历map,遍历一遍后再次进入内循环,map为空
    【转】Map 与 Unordered_map
    Chapter7 抑癌基因
    总结 搜索和最短路径问题
    1131 Subway Map DFS解法 BFS回溯!
    python 报错信息汇总
    python str转换成timedelta或date
  • 原文地址:https://www.cnblogs.com/yangk1996/p/12656396.html
Copyright © 2011-2022 走看看