一、多线程概念
一个任务就是一个程序,每个运行中的程序就是一个进程。当一个程序运行时,内部可能包含了多个顺序执行流,每个顺序执行流就是一个线程,在单线程的程序中,只有一个顺序执行流,而多线程的程序则可以包括多个顺序执行流,并且多个顺序流之间互不干扰。
线程是进程的执行单元,线程可以拥有自己的堆栈、自己的程序计数器和自己的局部变量,但不再拥有系统资源,它与父进程的其它线程共享父进程所拥有的全部资源。
二、线程的创建
线程的创建方式通常有3种:1)extends Thread继承Thread类,实现run方法;2)implements Runnable实现Runnable接口,实现run方法;3)implements Callable实现Callbale接口,实现call()方法。其中第三种方式能实现返回值,并且一般用FutureTask类来封装第三种方式的线程实现类,代码如下:
1) public class FirstThread extends Thread{
public void run(){
dosomething();
}
}
new FirstThread.start();
2) public class SecondThread implements Runnable{
public void run(){
dosomething();
}
}
new Thread(new SecondThread()).start;
3) public class ThirdThread implements Callable<Integer>{
public Integer call(){
int i;
dosomething();
return i
}
}
ThirdThread thirdThread =new ThirdThread();
FutureTask<Integer> task=new FutureTask<Integer>(thirdThread);
new Thread(task,"有返回值线程").start();
System.out.println("子线程返回值"+task.get());
三、线程生命周期
线程的5中状态:新建、就绪、运行、阻塞以及死亡。程序new一个线程后则该线程处于新建状态,此时线程仅仅由Java虚拟机为其分配了内存,并初始化了其成员变量的值,但未表现出任何线程的动态特征;当调用线程的start()方法后则线程处于就绪状态,Java虚拟机会为其创建方法调用栈和程序计数器,表示该线程一切就绪,就等JVM里线程调度器的调度;处于就绪状态的线程获得cpu后则进入运行状态了;线程调用sleep()、suspend()方法,或是IO阻塞,或是在wait则进入了阻塞状态;run()方法执行结束,或是线程抛出异常或是错误,或是调用stop()方法结束线程,则线程死亡。
四、线程控制
1)设置为守护进程(后台进程):threadInstance.setDaemon(true); 所有前台线程都死亡了,则后台线程会自动死亡。
2) 线程休眠:Thread.sleep(),线程调用sleep()方法后将进入阻塞状态,在此期间线程不会获得执行的机会,但不会放弃已获得的锁等资源。
3)线程让步:Thread.yield(),线程进入就绪状态,sleep方法会给其他线程执行机会,但yield方法只会给优先级相同或是更高的线程执行机会。
4)改变线程的优先级:setPriority: MAX_PRIORITY MIN-PRIORITY NORM_PRIORITY。
五、线程同步
1)同步代码块:synchronized(obj),其中obj为同步监视器。
2)同步方法:public synchronized void method(){}
3) 同步锁:Lock.lock(),Lock.unlock(); 当获取了多个锁时,它们必须以相反的顺序释放,且必须在与所有锁被获取时相同的范围内释放所有锁!
Lock有Condition来协调线程的调度,该类提供了await(),signal()以及signalAll()方法。
六、线程通信
1)线程协作方式:Object的wait、notify、notifyAll;以上第五部分的线程同步方式;
2)管道方式,
七、线程池
//固定的线程池,自定义线程数量 ExecutorService threadPool=Executors.newFixedThreadPool(3);
//动态的线程池,给几个任务,就自动创建几个线程 ExecutorService threadPool=Executors.newCachedThreadPool();
ExecutorService threadPool=Executors.newCachedThreadPool();
for(int i=0;i<10;i++){
final int task=i;
threadPool.execute(new Runnable(){
@Override
public void run() {
// TODO Auto-generated method stub
for(int j=1;j<=5;j++){
try{
Thread.sleep(20);
}
catch(InterruptedException e){
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName()
+" is looping of "+j+" for task of "+task);
}
}
});
//threadPool.shutdownNow();立即将线程池中的所有线程干掉.
//会报异常----java.lang.InterruptedException: sleep interrupted
}