第一章 多线程基础

一台主机连接若干个终端,每个终端有一个用户在使用。顺序执行的模式使得应用程序在运行时独占全部得计算机资源,资源利用率非常低。

1.1.2 线程与进程得关系
  1. 进程可以看成线程得容器,而线程又可以看成是进程中得执行路径。java得多线程机制是抢占式的,这表明调度机制会周期性地中断线程,将上下文切换到另一个线程。归根结底,线程就是应用程序在运行过程中,通过操作系统向cpu发起一个任务,这个任务只能访问当前进程的内存资源。
  2. 调用thread类的start方法,启动线程,向cpu发起请求,去执行任务。需要注意的是,执行start()方法的顺序不代表线程启动的顺序。为什么?主要因为任务的执行靠cpu,而处理器采用分片轮询方式执行任务,所有的任务都是抢占式的执行模式。任务不排序,可以设置优先级。任务被执行前,线程处于自旋等待状态。
1.2.1 线程标识
1.2.2 Thread与Runnable
1.2.3 run()与start()
  1. 调用Thread对象的start()方法,使线程对象开始执行任务,触发虚拟机调用当前线程对象的run方法。调用start()方法,将导致俩个线程并发运行,一个是调用start()方法的当前线程,另外一个是执行run()方法的线程。
1.2.4 thread源码分析

1.3 线程状态

线程在某个时间点,只能有一种状态。

public static void main(String[] args) {
        //锁对象
        Object object = new Object();
        //新建t1线程
        Thread t1 = new Thread(new Runnable() {
            @Override
            public void run() {
                //循环10次
                for (int i=0;i<10;i++){
                    //打印当前线程的名字+循环次数
                    System.out.println(Thread.currentThread().getName()+",i="+i);
                    //遇到第五次
                    if (i==5){
                        //使用锁对象
                        synchronized (object){
                            try {
                                //打印当前锁开始等待的标志
                                System.out.println(Thread.currentThread().getName()+"开始等待");
                                //使当前线程进入等待状态
                                object.wait();
                            }catch (Exception e){
                                
                            }
                        }
                    }
                }
            }
        });
        //创建线程二
        Thread t2 = new Thread(new Runnable() {
            @Override
            public void run() {
             //打印当前线程开始启动
                System.out.println(Thread.currentThread().getName()+"running...");
                synchronized (object){
                    try {
                        //打印当前线程开始向第一个线程发送notify通知...
                        System.out.println(Thread.currentThread().getName()+",发送notify通知");
                        object.notify();
                    }catch (Exception e){
                        
                    }
                }
            }
        });
        //启动第一个线程
        t1.start();
        //计算10000000次,等待一会
        double d =0;
        for (int i=0;i<1000000;i++){
            //等待第一个线程进入wait方法
            d+=(Math.PI+Math.E)/i;
        }
        //在主线程中读取第一个线程的状态
        System.out.println(t1.getName()+"状态:"+t1.getState());
        //启动第二个线程
        t2.start();
    }

aqs的基本原理

  • 可重入锁,公平锁,非公平锁
  • 公平锁:优点:所有线程都能得到资源,不会饿死在队列中。缺点:吞吐量下降,cpu唤醒阻塞线程开销大。