关于线程基础
A.
并发在java中本身就是无处不在,例如Servlet天生就是多线程的,还有一些后台线程,进程和线程出现的原因,基本都是为了更好更合理的利用资源,更公平!
如果是在单处理器上,那么并发从某种角度上看,就是将顺序执行的任务拆分成并发执行,算上上下文切换的开销,其实更花时间!但是有阻塞IO或者大计算的时候,如果没有并发,程序会停止。有了并发,其他任务还可以同时进行,更公平合理的分配了资源。
仅仅靠进程也可以实现并发,但是这里我们只讨论线程实现并发的方式!
B.
Java的Thread对线程的操作都是通过native方法,可以通过start方法开启一个线程,不过一个线程真正的事情是在run方法里做的,run方法只是普通的java方法,因此直接调用它,只是想相当于在当前线程调用一个普通方法,没什么意义, 因此要真正多线程就要实现Thread类重写run方法,并调用start方法启动!
另外,也可以将实现Runnable接口的类作为Thread类构造函数的参数,再调用start方法启动!
C.
1.
可以调用线程的静态sleep方法,实现线程休眠,它可以精确到纳秒,并且他响应中断,会抛出InterruptedException。另外,新版的API有了更显示的方法,就是
TimeUnit.MILLSECONDS.sleep(),本质上来说,还是调用Thread的sleep方法,但是因为sleep方法只接受毫秒和纳秒作为参数,因此TimeUnit实现了时间的转换,比如小时--à毫秒
2
线程之间也有一定的优先级,它是不确定的,高的执行平率高,低的执行平率低,但是不会有死锁,可以通过调用setPriority方法设置。
3
我们的主线程是用户线程(User Thread),另外还会有一些后台线程(守护线程,Daemon Thread),他们不是必须的,当所有非后台线程结束的时候,程序也就终止了,同时会杀死所有的后台线程。比如垃圾回收的线程!
4
从我们使用者的角度来说,没什么理由使用守护线程,因为他们随时可能终止,并且连finally方法也不会执行
一个线程可以等待另一个线程的结束,那就是在一个线程Al里面调用另一个线程B的join方法,表示A等待B,直到B结束。Java5以后提供了CountDownLatch和CycleBarrier等,也比较适合线程与线程之间的协作!
5
线程是有相对独立性的,在start方法之后,就和启动它的线程没关系了,因此我们也不能捕获到线程的异常,特别是运行时异常,只会在控制台打印!java5提供了Thread.UncaughtExceptionHandler接口,可以通过
Thread.setDefaultUncaughtExceptionHandler方法给所有线程注册异常处理器,也可以调用线程实例的setUncaughtExceptionHandler方法,为单独的线程设置处理器!
D
其他一些有趣的方法
println Thread.dumpStack()
println Thread.currentThread().state
//getAllStackTraces 一个Map获得所有线程的栈
Map map=Thread.getAllStackTraces()
println map.size()
List list=Thread.currentThread().getStackTrace()
//打出调用栈
list.each { println it }