- 概述
- 进程
- 正在运行的程序,是系统进行资源分配和调用的独立单位。
- 每一个进程都有它自己的内存空间和系统资源。
- 线程
- 是进程中的单个顺序控制流,是一条执行路径
- 一个进程如果只有一条执行路径,则称为单线程程序。
- 一个进程如果有多条执行路径,则称为多线程程序。
- 并行
- 逻辑上同时发生,指在某一个时间内同时运行多个程序。
- 并发
- 物理上同时发生,指在某一个时间点同时运行多个程序。
- Thread类的方法
- Thread.currentThread().getName();
- public final String getName();
- 线程的状态
- 被创建
- 2种方法(见下)
- 运行
- start()
- 具备CPU的执行资格和执行权,其实就是它正在被CPU处理
- 临时阻塞
- 具备执行资格,不具备执行权,等待被执行
- 冻结
- sleep(time)-Thread类的静态方法
- sleep()方法会抛出异常,你必须catch,不能抛出,因为父类的run()方法没有抛异常
- 不释放锁
- 必须指定time
- wait()-Object类的方法
- 丧失执行权和执行资格,释放锁
- 可以不指定时间
- sleep(time)-Thread类的静态方法
- 结束
- stop()
- 被创建
- 进程
- 多线程的2种方式
- 第一种方法:继承Thread类,然后复写run()方法,run()方法里就是线程需要执行的内容,然后创建对象调用start()方法来启动线程(JVM会调用run()方法)
- 如果只是单独调用run()方法的话,只意味着子类的对象在调用一个普通的函数而已,与线程的开辟无关
- 第二种方法(因为Java不支持多继承):实现Runnable接口,覆盖run()方法,创建Thread对象,且传入该类的对象,使用Thread对象调用start()方法
- 第一种方法:继承Thread类,然后复写run()方法,run()方法里就是线程需要执行的内容,然后创建对象调用start()方法来启动线程(JVM会调用run()方法)
- 线程安全
- 产生的原因
- 多个线程操作同一个共享数据
- 操作共享数据的代码有多条
- 当一条线程操作共享数据的过程中,其他线程参与了共享数据的运算,此时就出现了线程安全问题
- 解决办法
- 将操作共享数据的代码包装成同步代码块
- synchronized(obj){}
- 将操作共享数据的代码包装成同步代码块
- 产生的原因
- 同步
- 同步的前提
- 多个线程使用同一个锁!
- 同步的方式
- 1.同步代码块synchronized(obj){}
- 2.同步函数:给函数加synchronized修饰符
- 同步函数的锁:this;当然,同步代码块也可以使用this,synchronized(this)
- 静态synchronized同步函数使用的锁是这个函数所属的字节码的文件对象。这个锁可以使用this.getclass()获取,也可以使用类名.class来获取
- 同步的前提
- 死锁
- 产生原因
- 有2个锁,某个线程任务持有锁a,需要锁b才能继续执行代码,而另一个线程任务此时持有锁b,在等待锁a执行其剩余代码。
- 产生原因
- 线程间通信
- 多个线程处理同一个资源,但是任务不同,比如一存一取
- 等待唤醒机制
- 用于存一取一,多存多取(要用到while循环判断,notifyAll()方法唤醒线程池中所有的线程),区别于只多条取
- 方法,这些方法必须定义在同步中,因为需要明确到底是操作的哪个锁上的线程:
- 要调用这些方法,需要用监视器去调用。而监视器可以是任意的对象,所以这些方法都定义在Object中(注意,监视器和锁的区分)
- wait();(让线程进入线程池,不会被赋予执行资格,会释放执行权,释放锁!),
- notify();(唤醒线程池中的任意线程),
- notifyAll();(唤醒线程池中的所有线程)
- (以上3个方法的调用者,必须和同步使用的锁是一致的!)
- 1.5新特性
- Lock lock =new ReentrantLock();
- 定义一个锁,用来标识需要进行同步的线程执行内容
- 开始结束标示:lock.lock();lock.unlock();(通常定义在finally代码块中)
- Condition c =lock.newCondition();
- 定义一个监视器,可以定义多个
- c具有Object监视器的对线程操作的方法:await();signal();signalAll();
- Lock lock =new ReentrantLock();
- 线程相关的方法
- 中断线程的方法
- stop()方法--已过时
- run()方法结束
- 一般都有循环结构,控制循环条件的话,就可以控制线程结束的条件
- interrupt()方法的使用
- 用于中断线程的wait()、sleep()状态,同时抛出一个interruptedException
- interrupt()方法不会中断一个正在运行的线程。这一方法实际上完成的是,在线程受到阻塞时抛出一个中断信号,这样线程就得以退出阻塞的状态。更确切的说,如果线程被Object.wait, Thread.join和Thread.sleep三种方法之一阻塞,那么,它将接收到一个中断异常(InterruptedException),从而提早地终结被阻塞状态
- 注意要处理InterruptedException
- setDaemon
- public final void setDeamon(boolean on)
- 将一个线程设置为后台线程或者用户线程,当所剩线程全部都是daemon线程后,JVM退出
- on为true的时候设置线程为Daemon
- 需要在线程启动前就设置
- join()方法
- 线程t start()以后,t.join()了,那么当前线程会等你t结束后,当前线程才会获得CPU执行资格
- 抛出InterruptedException
- 线程的priority
- 1-10,数字越大,优先级越高
- setPriority(Thread.MAX_PRIORITY);
- 设置优先级
- 中断线程的方法
转载于:https://www.cnblogs.com/wonewo/p/9440189.html