多线程编程

2020-12-27  本文已影响0人  NengLee

什么是进程?

​ 进程可以说是一个"执行中程序",是操作系统进行资源分配和调度的一个地独立单位,是应用程序运行的载体。

什么是线程?

​ 线程(thread)是操作系统能够进行运算调度的最小单位,它被包含在进程之中,是进程中的实际运作单位。

类比OOP思想,进程如果是火车,那么线程就是车厢

区别

  1. 线程是程序执行的最小单位,而进程是操作系统分配资源的最小单位,线程执行任务,进程不执行是载体
  2. 一个进程有一个或者多个线程组成,线程是一个进程中代码的不同执行路线
  3. 进程之间相互独立,但是同一个进程下个各个线程共享程序内存空间
  4. 调度和切换:线程上下文切换比进程上下文切换的要快

多线程

​ 多线程是指在单位程序中可以同时运行多个不同线程,执行不同任务

​ 比单线程更具有优势:

并行和并发

​ Erlang 之父 Joe Armstrong 用一张5岁小孩都能看懂的图解释了并发与并行的区别

并行与并发

​ 并行:同时执行任务。

​ 并发:交替运行任务。

不能脱开时间线概念,例如一分钟并发量,一分钟的时间内有多少任务执行完毕。

多线程创建方式

  1. 继承Thread,重写run方法

  2. 实现Runnable接口,重写run方法

区别: Thread是对线程的程序,Runnable对任务/逻辑的抽象

如何停止终止线程

1. stop() 具有暴力销毁
    @Deprecated
    public final void stop() {
        stop(new ThreadDeath());
    }

    @Deprecated
    public final void stop(Throwable obj) {
        throw new UnsupportedOperationException();
    }


    public class ThreadDeath extends Error {
        private static final long serialVersionUID = -4417128565033088268L;
    }
2. interrupt()、interrupted()、isinterrpted() 标志函数

interrupt()... 源码

/**
*将线程的中断标记设置为true,但不会停止线程
*/
public void interrupt() {
    if (this != Thread.currentThread())
        checkAccess();

    synchronized (blockerLock) {
        Interruptible b = blocker;
        if (b != null) {
            interrupt0();           // Just to set the interrupt flag
            b.interrupt(this);
            return;
        }
    }
    interrupt0();
}

/**
 *静态获取,测试当前线程(当前线程是指运行interrupted()方法的线程)是否已经中断,且清除中断状态
 */
public static boolean interrupted() {
    return currentThread().isInterrupted(true);
}

/**
 *测试线程(调用该方法的线程)是否已经中断,不清除中断状态。
 */
public boolean isInterrupted() {
    return isInterrupted(false);
}

/**
 * privat - 设置
 */
private native boolean isInterrupted(boolean ClearInterrupted);

参考:

@Test
public void testMain() throws InterruptedException {
    MyThread myThread = new MyThread();
    myThread.start();
    System.out.println("=== testMain1 :" + myThread.getName() + "   " + myThread.isInterrupted());
    myThread.interrupt(); //中断线程,标识
    System.out.println("=== testMain2 :" + myThread.getName() + "   " + myThread.isInterrupted());
}


class MyThread extends Thread {
    @Override
    public void run() {
        System.out.println("继承Thread,重写run方法" + Thread.currentThread().getName());
        System.out.println(Thread.currentThread().getName() + " Top   interrupt is " + isInterrupted());
        while (true) {
            try {
                Thread.sleep(100);
                System.out.println(Thread.currentThread().getName() + " while  try  interrupt: " + isInterrupted());
            } catch (InterruptedException e) {
                e.printStackTrace();
                System.out.println(Thread.currentThread().getName() + " while  catch  interrupt: " + isInterrupted());
                Thread.currentThread().interrupt(); //手动修改处
                System.out.println(Thread.currentThread().getName() + " while  catch  interrupt: " + isInterrupted() + "  (手动修改后)");
            }
            System.out.println("run End  while");
        }

    }
}
Logs输出

线程的生命周期

线程的生命周期

start()

​ 启动线程之后才有关联起来,不是new Thread()关联,这里只获取对象 Thread parent = currentThread();

join()

​ 关联线程,串行可以调度 xxxThread等待就绪的线程,在此优先执行

yield()

​ 让当前Thread交时间片,CPU重新(包括当期让出)交给其他Thread

sleep(millis)

​ 当前Thread处于阻塞,挂起Time后在就绪,重新等待CPU时间轮转

wait()

​ Object对象的方法,如果没有设置时间,需要通过notify进行唤醒

stop()

​ 暴力销毁线程,会释放资源锁,如在多线程会出现不可Error

setDeamon()

​ 设置当前线程为守护线程,依赖其他线程,如进程中的所有线程执行完毕,守护线程也会跟着销毁,多用于辅助维护线程

上一篇下一篇

猜你喜欢

热点阅读