基本概念

  • 进程:
    正在运行的程序,是系统进行资源分配和调用的独立单位。
    每一个进程都有它自己的内存空间和系统资源。
  • 线程:
    在同一个进程内又可以执行多个任务,而这每一个任务我就可以看出是一个线程。
    线程:是程序的执行单元,执行路径。是程序使用CPU的最基本单位。
    是进程中的单个顺序控制流,是一条执行路径
    一个进程如果只有一条执行路径,则称为单线程程序。
    一个进程如果有多条执行路径,则称为多线程程序。
  • 多进程意义:
    单进程的计算机只能做一件事情,而我们现在的计算机都可以做多件事情。
    举例:一边玩游戏(游戏进程),一边听音乐(音乐进程)。
    也就是说现在的计算机都是支持多进程的,可以在一个时间段内执行多个任务,可以提高CPU的使用率。
    多线程的存在,不是提高程序的执行速度。其实是为了提高应用程序的使用率。
    程序的执行其实都是在抢CPU的资源,CPU的执行权。
    多个进程是在抢这个资源,而其中的某一个进程如果执行路径比较多,就会有更高的几率抢到CPU的执行权。
    我们是不敢保证哪一个线程能够在哪个时刻抢到,所以线程的执行有随机性。
    问题:
    一边玩游戏,一边听音乐是同时进行的吗?
    不是。因为单CPU在某一个时间点上只能做一件事情
    而我们在玩游戏,或者听音乐的时候,是CPU在做着程序间的高效切换让我们觉得是同时进行的。
  • 线程生命周期

一个线程实现进队列 一个线程实现出 Java 实现挂号 一个线程_java

  • 常见方法说明及使用:
  1. Thread.currentThread().getName()
    获取main方法所在的线程对象的名称
  2. join()
    把指定的线程加入到当前线程
    eg:在线程B中调用了线程A的Join()方法,直到线程A执行完毕后,才会继续执行线程B
    注:Join方法实现是通过wait(小提示:Object 提供的方法)。 当main线程调用t.join时候,main线程会获得线程对象t的锁(wait 意味着拿到该对象的锁),调用该对象的wait(等待时间),直到该对象唤醒main线程 ,比如退出后。这就意味着main 线程调用t.join时,必须能够拿到线程t对象的锁。
  3. notify() / notifyAll()
    唤醒当前对象上的等待线程。notify() 唤醒不确定的一个线程 notifyAll() 唤醒所有线程
  4. wait()
    让当前线程进入等待(阻塞)状态,直到其他线程调用此对象的notify()方法或 notifyAll() 方法,或者超过指定的时间量”,当前线程被唤醒(进入“就绪状态”)
    注:
    1.会让当前线程释放它所持有的锁
    2.来自Object类
  5. suspend()
  6. resume()方法
    两个方法配套使用,suspend()使得线程进入阻塞状态,并且不会自动恢复,必须其对应的resume()被调用,才能使得线程重新进入可执行状态。典型地,suspend()和 resume() 被用在等待另一个线程产生的结果的情形:测试发现结果还没有产生后,让线程阻塞,另一个线程产生了结果后,调用 resume()使其恢复。
注:wait() 和 notify() 方法与suspend()和 resume() 区别

suspend()及其它所有方法在线程阻塞时都不会释放占用的锁(如果占用了的话),而wait() 和 notify() 这一对方法则相反。

  1. yield()
    暂停当前正在执行的线程对象,并执行其他线程。
    让多个线程的执行更和谐,但是不能靠它保证一人一次。
  2. sleep()
    eg:Thread.sleep(3000) 让当前正在运行的占用cpu时间片的线程挂起3000ms,把cpu的时间片交给其他线程,具体交给哪个线程不一定,需要线程竞争cpu
注:sleep() 和 yield()都定义在Thread.java中
  1. interrupt()
    中断线程,把线程的状态终止,并抛出一个InterruptedException
wait和sleep的区别

相同点:

  1. 他们都是在多线程的环境下,都可以在程序的调用出阻塞指定的毫秒数并且返回
  2. 两个方法都可以通过interrupt()方法打断线程的暂停状态,但是线程会抛出InterruptedException。需要注意的是,InterruptedException是线程自己从内部抛出的,并不是interrupt()方法抛出的。对某一线程调用 interrupt()时,如果该线程正在执行普通的代码,那么该线程根本就不会抛出InterruptedException。但是,一旦该线程进入到 wait()/sleep()/join()后,就会立刻抛出InterruptedException 。

不同点:

  1. Thread类的方法:sleep(),yield()
    Object的方法:wait()和notify()、notifyAll()
  2. 每个对象都有一个锁来控制同步访问。Synchronized关键字可以和对象的锁交互,来实现线程的同步。 sleep方法没有释放锁,而wait方法释放了锁,使得其他线程可以使用同步控制块或者方法。
  3. wait,notify和notifyAll只能在同步控制方法或者同步控制块里面使用,而sleep可以在任何地方使用 。注意:wiat()必须放在synchronized block中,否则会在program runtime时扔出“java.lang.IllegalMonitorStateException”异常。
  4. sleep必须捕获异常,而wait,notify和notifyAll不需要捕获异常

综上可得两者最大的区别:sleep()睡眠时,保持对象锁,仍然占有该锁;而wait()睡眠时,释放对象锁。