基本定义
进程:每个进程都有独立的代码和数据空间,进程间的切换会有较大开销,每个进程含有1-n个线程。
线程:同一类线程共享代码和数据空间,每个线程有独立的运行栈和程序计数器。
五个阶段:创建、就绪、运行、阻塞、终止
实现多线程的方法有两种:
1. 继承Thread类 extends Thread run(){} Thread.start()
2. 实现Runnable接口 implements Runanable @override run()
推荐使用Runnable接口,真正实现多个相同的程序代码的线程去处理同一个资源,去掉了单线程的限制。
多线程中的一些概念
优先级:MAX MIN NORM_PRIORITY,Tread.setPriority(Thread.MAX_PRIORITY)更改优先级
睡眠:Thread.sleep(long mills) 转到阻塞状态
等待:Object类的wait方法,其他线程调用notify()或notifyAll()唤醒
让步:Thread.yeild()将线程从运行状态转到可运行状态,但有可能没有结果,与sleep的差别,让步的线程和其他线程拥有相同的优先级获得cpu,sleep使当前线程进入停滞状态,在指定的时间内肯定不会被执行。
加入:Thread.join() 当前线程调用另一个线程的join(),当前线程进入阻塞,另一个线程挖成再继续,主线程生成并启动子线程,若子线程耗时很长,定以后调用子线程的t.join()方法,让主线程在子线程结束后再结束
唤醒: Object.notify()唤醒当前对象监控器上等待的单个线程
中断:interrupt,粗暴,资源未关闭。
注:obj.wait()和obj.notify必须在synchronized(obj){}语句块内。
Sleep()和wait()共同点:在多线程环境下,都可以在程序的调用处阻塞指定的毫秒数,并返回,都可以通过interrupt()方法打断线程的暂停状态,从而使线程立刻抛出InterruptedException。
区别:
1. Thread类的方法:sleep(),yield()等,Object的方法:wait()和notify()等。
2. 每个对象都有一个锁来控制同步访问。Synchronized关键字可以和对象的锁打交道,Sleep睡眠时,保持对象锁,仍然占有该锁,wait睡眠时,释放该对象锁。
3. wait,notify和notifyAll只能在同步控制方法或者同步控制块里面使用,而sleep可以在任何地方使用
4. sleep必须捕获异常,而wait,notify和notifyAll不需要捕获异常
主线程:JVM调用程序main()所产生的线程。
当前线程:这个是容易混淆的概念。一般指通过Thread.currentThread()来获取的进程。
后台线程:指为其他线程提供服务的线程,也称为守护线程。JVM的垃圾回收线程就是一个后台线程。用户线程和守护线程的区别在于,是否等待主线程依赖于主线程结束而结束
前台线程:是指接受后台线程服务的线程,其实前台后台线程是联系在一起,就像傀儡和幕后操纵者一样的关系。傀儡是前台线程、幕后操纵者是后台线程。由前台线程创建的线程默认也是前台线程。可以通过isDaemon()和setDaemon()方法来判断和设置一个线程是否为后台线程。
线程类的一些常用方法:
sleep(): 强迫一个线程睡眠N毫秒。
isAlive(): 判断一个线程是否存活。
join(): 等待线程终止。
activeCount(): 程序中活跃的线程数。
enumerate(): 枚举程序中的线程。
currentThread(): 得到当前线程。
isDaemon(): 一个线程是否为守护线程。
setDaemon(): 设置一个线程为守护线程。(用户线程和守护线程的区别在于,是否等待主线程依赖于主线程结束而结束)
setName(): 为线程设置一个名称。
wait(): 强迫一个线程等待。
notify(): 通知一个线程继续运行。
setPriority(): 设置一个线程的优先级。