Java多线程基本概念回顾
-------------------------------
线程又称轻量级进程,它和进程一样有独立的执行控制,由操作系统负责调度。区别在于线程没有独立的存储空间,而是和所属进程中其它的线程共享一个存储空间。
每条线程都有自己的工作内存,工作内存中保存的是主存中某些变量的拷贝,线程对所有变量的操作都是在工作内存中进行,线程之间无法相互直接访问,变量的传递均需要通过主存完成。
Java中执行多线程:
1、继承Thread。
2、实现Runnable接口。
然后重写run方法。
线程的4种状态:
1、新建:线程已被创建但尚未执行。
2、可执行:可以被执行,但不一定正在执行,如果CPU分配了该线程时间片,该线程就执行。
3、阻塞:线程不会被分配CPU时间片。
4、死亡:一般在run方法执行完后,线程就会死亡。
线程的同步:
由于同一进程的多个线程共享同一片存储空间,在带来方便的同时,也带来了访问冲突这个问题。
解决方法:使用synchronized方法或synchronized块。
Java中每个类的实例对应一把锁,每个synchronized方法都必须获得实例的锁才能执行,否则所属线程阻塞。
方法一旦执行,就独占该锁,直到从该方法返回才释放锁。
Java中每个类也对应一把锁,可将类的静态成员方法声明为synchronized方法,以控制其对类静态成员变量的访问。
线程的阻塞:
阻塞是指暂停一个线程的执行以等待某个条件的发生。Java提供了大量的方法来支持阻塞。
1、sleep():使线程在指定时间内进入阻塞状态,不能得到CPU时间。
2、yield():使线程放弃当前时间片,但不阻塞,而是进入可运行状态。
3、join():让当前线程阻塞以等待特定线程的消亡。
4、wait()和notify()方法:
线程sleep()时不会释放占用的锁,而线程wait()会释放占用的锁。
notify()会将因调用该对象wait()而阻塞的线程中随机选择一个解除阻塞(但要等到获得锁后才真正可以执行)。
注意:
wait()和notify()方法必须在synchronized方法中调用(即必须在获得锁时调用)。
notifyAll()方法会将因调用wait()而阻塞的所有线程全部解除阻塞,而只有获得锁的那一个线程才能进入可执行状态。
守护线程:
是一类特殊的线程,与普通线程的区别在于它并不是程序的核心部分。
只要有一个非守护线程在运行,程序就不会终止。如果所有非守护线程都终止,程序就会终止。
守护线程用于后台为其它线程提供服务,setDeamon()方法将一个线程设置为守护线程。
线程池:
解决问题:为每个请求都创建一个新线程开销很大,在JVM里创建太多线程可能会导致系统过度消耗内存或者"切换过度"。