java 多线程以及线程池
1.多线程可以使程序反应更快,交互性更强,执行效率最高。
2.创建一个线程: 要实现Runnable 接口,创建Thread类的对象,用start开始执行线程。
3.使用Thread中的yield()方法为其他线程临时让出CPU时间。
4.sleep()方法可以将线程设置为休眠状态以确保其他线程执行。休眠时间为毫秒数·。
sleep()方法可能抛出一个InterruptedException.这是一个必捡异常。需要try-catch块中。
yield()方法为其他线程临时让出CPU时间。
· join()方法使一个线程等待另一个线程的结束。
5.start()方法使启动一个线程。
run()方法是线程启动后要进行回调的方法。
sleep执行后线程进入阻塞状态,不考虑线程优先级
yield执行后线程进入就绪状态,只会给相同优先级或者更高优先级线程运行机会。
join执行后线程进入阻塞状态
sleep() 后线程不释放锁,跟此线程 共享所的 线程 都被阻塞,但不影响其他线程运行。固定时间后,等待CPU调度。
await() 后线程释放锁,所有线程都有机会执行。并且等待 其他线程 通过signal()方法唤醒。
await() 和 signal()是成对出现的。是Thread 类的方法。
wait() 和 notify() 是成对出现的。是object类的方法。
线程的sleep()方法和yield()方法有什么区别?
答:
① sleep()方法给其他线程运行机会时不考虑线程的优先级,因此会给低优先级的线程以运行的机会;yield()方法只会给相同优先级或更高优先级的线程以运行的机会;
② 线程执行sleep()方法后转入阻塞(blocked)状态,而执行yield()方法后转入就绪(ready)状态;
③ sleep()方法声明抛出InterruptedException,而yield()方法没有声明任何异常;
④ sleep()方法比yield()方法(跟操作系统CPU调度相关)具有更好的可移植性。
5.java为每个线程都设置一个优先级。默认情况下,线程继承他的线程的优先级。可以用setPriorty方法提高或者降低优先级。还可以用getPriorty方法获取优先级。
优先级是1-10的数字。MIN_PRIORITY,NORM_PRIORITY,MAX_PRIORITY,分别代表1,5,10.
主线程的优先级是Thread.NORM_PRIORITY。
如果,线程的优先级相同,那么将会用循环队列给他们分配相同的CPU份额。被称为 循环调度。
6.Thread中还包含 stop(),suspend(),resume()。方法,但是存在不安全因素。不提倡使用这些方法。
使用线程池的好处
1.通过重复利用已创建的线程, 减少在创建和销毁线程上所花的时间以及系统资源的开销。
2.提高响应速度。 当任务到达时, 任务可以不需要等到线程创建就可以立即行。
3.提高线程的可管理性。 使用线程池可以对线程进行统一的分配和监控。
4.如果不使用线程池, 有可能造成系统创建大量线程而导致消耗完系统内存。
线程池的注意事项
虽然线程池是构建多线程应用程序的强大机制, 但使用它并不是没有风险的。
(1) 线程池的大小。 多线程应用并非线程越多越好, 需要根据系统运行的软硬件环境以及应用本身的特点决定线程池的大小。 一般来说, 如果代码结构合理的话, 线程数目与 CPU数量相适合即可。 如果线程运行时可能出现阻塞现象, 可相应增加池的大小; 如有必要可采用自适应算法来动态调整线程池的大小, 以提高 CPU 的有效利用率和系统的整体性能。
(2) 并发错误。 多线程应用要特别注意并发错误, 要从逻辑上保证程序的正确性, 注意避免死锁现象的发生。
(3) 线程泄漏。 这是线程池应用中一个严重的问题, 当任务执行完毕而线程没能返回池中就会发生线程泄漏现象。
线程的基本状态以及状态之间的关系?
说明:其中Running表示运行状态,Runnable表示就绪状态(万事俱备,只欠CPU),
Blocked表示阻塞状态,阻塞状态又有多种情况,可能是因为调用wait()方法进入等待池,也可能是执行同步方法或同步代码块进入等锁池,或者是调用了sleep()方法或join()方法等待休眠或其他线程结束,或是因为发生了I/O中断。
synchronized 和 lock 区别:
Synchronized 是 Java的关键字,采用Synchonized关键字实现同步时,如果多个线程只是进行 读操作,当一个线程进行读操作时,其他线程不能执行读操作。
Lock 是 一个类,Lock.lock()方法创建锁。在对 lock()的调用后紧随一个try-catch块并且在finally子句中释放这个锁。【lock.unlock()】
使用Synchronized时不需要 手动的去释放锁,当Synchronized方法或者代码块执行结束后,系统会自动让线程释放锁;而lock则需要用户手动去释放锁,如果没有释放锁,则会导致死锁现象。