- 面试知识点 Reference:http://blog.jobbole.com/76308/
Runnable可以避免Thread方式由于java当继承特性所带来的缺陷
Runnable的代码可以被多个线程(Thread实例)共享,适合多个线程处理统一资源情况、
线程生命周期 创建 –> 就绪 –>运行 ( –> 阻塞 –> 就绪 ) –> 终止
创建: Thread thread = new Thread();
就绪:thread.start() –> 进入就绪队列,等待获取CPU服务。不一定开始运行(可能当前cpu被其他占用)
运行状态:获取到cpu. 开始执行run方法的里面的逻辑。
阻塞:由于某种原因,当前运行的线程让出cpu资源,暂停自己的执行,便进入阻塞状态。例如调用sleep()、wait()。当定时或则自动唤醒后,进入就绪状态,等待cpu资源。
终止:线程的run()方法执行完毕,或则被人为thread.stop()方法调用。
Java线程分为两类
- 用户线程:
运行在前台,执行具体任务。
程序的主线程、连接网络的子线程等都是用户线程。
- 守护线程:
运行在后台,为其他前台线程服务。一旦所有用户线程都结束运行,守护线程随JNM一起结束工作。
数据库连接池中的检测线程。JVM虚拟机启动后的检测线程。垃圾回收线程。
设置守护线程: http://www.imooc.com/video/6310
调用Thread类的setDaemon(true)方法设置当前线程为守护线程。
1.setDaemon(true)方法必须在start()方法签调用,否则会抛出IllegalThreadStateException异常
2.守护线程中产生的新线程也是守护线程
3.不是所有任务都可以分配给守护线程执行,如读写操作或计算逻辑。
http://blog.chinaunix.net/uid-26430381-id-3746859.html
http://blog.youkuaiyun.com/yake25/article/details/7522366
操作系统线程知识:
多个程序同时运行在CPU的情况叫做多道程序。
进程的出现,解决了程序并发执行时对系统资源共享的描述问题,同时顺路解决了程序执行时动态特征的描述问题。
从进程创建,撤销,到状态转换中的阻塞,唤醒,挂起,激活,同时还有进程间优先级的控制。这些控制指令都是通过“原语”实现的,这个词不出意外最先是在数据库基础知识中学到的,对滴,不能被打断,打断就抛弃结果。对于系统,没有被打断的可能性。
线程是进程中的一个实体,是调度的基本单位。
互斥使用临界资源
l 当进程需要使用临界资源时,通过获得临界区的使用权实现。
l 首先,在“进入区”判断是否可以进入临界区,如果可以进入,则必须设置临界区使用标志,阻止其他后来的进程进入临界区(比如插个旗子),后来的进程通过查看临界区使用标志,知道自己不能进入临界区,就进入阻塞队列,将自己阻塞。
l 当临界区内的进程使用完毕,退出临界区时,即在“退出区”修改临界区使用标志,并负责唤醒阻塞队列中的一个进程,让其进入临界区。
临界区使用原则(互斥条件)
l 忙则等待:每次只允许一个进程处于临界区,如果临界区是占用的,其他进程必须等待;
l 有限等待:进程只能在临界区内逗留有限时间,不得使其他进程在临界外无限期等待;
l 空闲让进:如果临界区空闲,则只要有进程申请就立即让其进入;
l 让权等待:进入临界区的进程,不能在临界区内长时间阻塞等待某事件,必须在一定期限内退出临界区。(在临界区内要申请资源,必须退出)。
*************核心方法类******
package test.com;
class Queue
{
int value;
boolean bFull = false;
public synchronized void put(int i) {
if (!bFull) {
value = i;
bFull = true;
notify();// 必须用在synchronized
}
try {
wait();// 必须捕获异常
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public synchronized int get() {
if (!bFull)
try {
wait();//进入
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
bFull = false;
notify();
return value;
}
}
*****************************************************************
************************生产者类********************************
package test.com;
class Producter extends Thread {
Queue q;
Producter (Queue q) {
this.q=q;
}
public void run() {
System.out.println("********producter****start*****");
for(int i=1;i<10;i++) {
System.out.println("producter :"+i);
q.put(i);
}
System.out.println("********producter*****end****");
}
**********************************************************************
****************************消费者类*********************************
package test.com;
class Consumer extends Thread {
Queue q;
Consumer(Queue q) {
this.q=q;
}
public void run() {
System.out.println("********Consumer****start*****");
while(true) {
System.out.println("Consumer:"+q.get());
System.out.println("********Consumer****end*****");
}
}
}
************************************************************************
*******************************主函数调用类**********************************
package test.com;
public class Test {
public static void main(String[] args) {
Queue q=new Queue();
Producter p=new Producter(q);
Consumer c=new Consumer(q);
p.start();
c.start();
}
}
*******************************************************
OK,实现完毕
wait方法——把线程放入wait set
notify方法——从wait set拿出线程
notifyAll方法——从wait set拿出所有线程
wait、notify、notifyAll是Object类的方法