Java并发编程-01 线程与并发

进程和线程

进程

1)进程就可以视为程序的一个实例。大部分程序可以同时运行多个实例进程(例如记事本、画图、浏览器 等),也有的程序只能启动一个实例进程(例如网易云音乐、360 安全卫士等)。

2)系统进程:用于完成操作系统的各种功能的进程,它们就是处于运行状态下的操作系统本身

3)用户进程:就是所有由用户本身启动的进程

4)站在操作系统的角度,进程是程序运行资源分配(以内存为主)的最小单位

线程

1)有限的CPU运行多个程序:CPU调度多个进程中的线程

2)线程是CPU调度的最小单位

3)线程必须依赖于进程而存在,线程是进程中的一个实体,是能独立运行的基本单位

4)线程拥有在运行中必不可少的资源(如程序计数器,一组寄存器和栈)

5)线程可与同属一个进程的其他的线程共享进程所拥有的全部资源

6)一个进程可以拥有多个线程,一个线程必须有一个父进程

7)早期Linux的线程实现几乎就是复用的进程,后来才独立出自己的API。

上下文切换

CPU从一个进程或线程到另一个进程或线程的切换

上下文是CPU寄存器和程序计数器在任何时间点的内容

一次上下文切换大概需要5000~20000个时钟周期,相对一个简单指令几个乃至十几个左右的执行时钟周期,成本巨大

过程

1)暂停一个进程的处理,将该进程的CPU状态(即上下文)存储在内存中的某个地方

2.)从内存中获取下一个进程的上下文,并在CPU的寄存器中恢复它

3.)回到程序计数器指示的位置(即返回到进程被中断的代码行)以恢复进程

寄存器

寄存器是CPU内部的一小部分非常快的内存(相对于CPU内部的缓存和CPU外部较慢的RAM主内存),通过提供对常用值的快速访问来加快计算机程序的执行

程序计数器

是一种专门的寄存器,指示CPU在其指令序列中的位置,并保存着正在执行的指令的地址或下一条要执行的指令的地址

并行和并发

并行 

并行(parallel):指在同一时刻,有多条指令在多个处理器上同时执行。所以无论从微观还是从宏观来看,二者都是一起执行的。 并行在多处理器系统中存在

并发

 并发(concurrency):指在同一时刻只能有一条指令执行,但多个进程指令被快速的轮换执行,使得在宏观上具有多个进程同时执行的效果,但在微观上并不是同时执行的,只是把时间分成若干段,使多个进程快速交替的执行。并发可以在单处理器和多处理器系统中都存在。

Java线程

内置线程
1)Java 程序入口是 main()方法,执行 main()方法的线程是 main 线程
2) Reference Handler// 清除 Reference 的线程
3)Finalizer // 调用对象 finalize 方法的线程
4)Signal Dispatcher // 分发处理发送给 JVM 信号的线程
5)Attach Listener // 内存 dump ,线程 dump ,类信息统计,获取系统属性等
6) Monitor Ctrl-Break // 监控 Ctrl-Break 中断信号的线程
启动线程的方式

1)继承thread

public class MyThread extends Thread {

    public static void main(String[] args) {
        MyThread thread = new MyThread();
        thread.start();
    }

    /**
     * 重写Thread类的run(),这个方法称为线程执行体
     */
    @Override
    public void run() {
        doSomething();
    }

    /**
     * 需要处理的任务
     */
    public void doSomething() {
       
    }
}

2)实现runnable

public class MyRunnable implements Runnable {


    public static void main(String[] args) {
        MyRunnable runnable = new MyRunnable();
        Thread thread = new Thread(runnable);
        thread.start();

    }

    /**
     * 实现Runnable接口的run方法,这个方法称为线程执行体
     * */
    @Override
    public void run() {
        doSomething();
    }

    /**
     * 需要处理的任务
     * */
    private void doSomething(){
       
    }
}

3)实现Callable接口

public class MyCallable implements Callable<String> {

    public static void main(String[] args) {
        Callable<String> callable = new MyCallable();
        FutureTask<String> task = new FutureTask<>(callable);
        new Thread(task).start();
        try {
            System.out.println(task.get());
        } catch (InterruptedException | ExecutionException e) {
            e.printStackTrace();
        }
    }

   

    @Override
    public String call() throws Exception {
        doSomething();

        return "返回值";
    }

    public String doSomething() {
        return “返回值”;
    }
}

4)线程池

public class ThreadPool implements Runnable {

    private String name;

    public static void main(String[] args) {
       ExecutorService pool = Executors.newFixedThreadPool(2);
       ThreadPool threadPoolA = new ThreadPool("A");
       ThreadPool threadPoolB = new ThreadPool("B");
       pool.execute(threadPoolA);
       pool.execute(threadPoolB);
       pool.shutdown();
    }


    public ThreadPool(String name) {
        this.name = name;
    }

    @Override
    public void run() {
        doSomething();
    }

    /**
     * 需要处理的任务
     * */
    private void doSomething() {
       
    }
}

run()和start()
1)Thread 类是 Java 对线程概念的抽象,new Thread() 只是 new 出一个 Thread 实例。
2)Thread start 方法中调用了 start0()方法,而 start0()是个 native 方法 (操作系统线程)
3)start() 方法让一个线程进入就绪队列等待分配 cpu ,分到 cpu 后才调用实现 的 run() 方法
4)start() 方法不能重复调用,如果重复调用会抛出异常
5)run 方法是业务逻辑实现的地方,本质上和任意一个类的任意一个成员方法并没有任何区别,可以重复执行,也可以被单独调用
中止

1)自然终止  run 执行完成或者抛出了一个未处理的异常导致线程提前结束。

2)stop 
暂停suspend()、恢复resume()和停止stop()这些 API 是过期的,不建议使用。
suspend()方法调用后,线程不会释放已经占有的资源(比如锁),而是占有着资源进入睡眠状态,这样容易引发死锁问题。stop()方法在终结一个线程时不会保证线程资源正常释放,会导致程序工作在不确定状态下。
3)中断

interrupt(): 将线程的中断标志位设置为true,不会停止线程

isInterrupted(): 判断当前线程的中断标志位是否为true,不会清除中断标志位

interrupted():判断当前线程的中断标志位是否为true,并清除中断标志位,重置为fasle

中断机制是一种协作机制,并不能直接终止另一个线程,而需要被中断的线程自己处理。

被中断的线程拥有完全的自主权,它既可以选择立即停止,也可以选择一段时间后停止,也可以选择压根不停止。

4)优雅停止线程

while (!Thread.currentThread().isInterrupted() && more work to do) {

   ......

}

sleep可以被中断 抛出中断异常:sleep interrupted, 清除中断标志位

wait可以被中断 抛出中断异常:InterruptedException, 清除中断标志位

线程的状态

1)初始 (NEW) :新创建了一个线程对象,但还没有调用 start() 方法。
2)运行 (RUNNABLE) Java 线程中将就绪( ready )和运行中( running )两种
状态笼统的称为“运行”。 线程对象创建后,其他线程( 比如 main 线程)调用了该对象的 start() 方法。 该状态的线程位于可运行线程池中,等待被线程调度选中,获取 CPU 的使用权,
此时处于就绪状态( ready )。就绪状态的线程在获得 CPU 时间片后变为运行中
状态( running )。
3)阻塞 (BLOCKED) :表示线程阻塞于锁。
4)等待 (WAITING) :进入该状态的线程需要等待其他线程做出一些特定动作
(通知或中断)。
5)超时等待 (TIMED_WAITING) :该状态不同于 WAITING ,它可以在指定的时
间后自行返回。
6)终止 (TERMINATED) :表示该线程已经执行完毕。
流程图:

待补充..

线程间的通信

volatile

wait notify

LockSupport

管道输入输出流

join

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值