1、概述html
到第八节,就把多线程基本的概念都说完了。把前面的全部文章加链接在此:java
Java多线程——<一>概述、定义任务windows
Java多线程——<二>将任务交给线程,线程声明及启动多线程
Java多线程——<三>简单的线程执行:Executoride
均是我的理解和总结,代码均来自《thinking in java》,有问题欢迎你们指正。线程
2、多线程的其余概念
1.休眠
休眠,其实就是让线程暂停一段时间,也就是阻塞一段时间。例如:每一个打印以后,每一个线程都要睡眠(即阻塞),这使得线程调度器能够切换到另外一个线程,进而驱动另外一个任务。这致使了线程在执行顺序上获得了保证,能够经过查看打印输出消息证明这一点。
public class TaskSleepingTask extends Task{ @Override public void run() { try{ while(countDown-- > 0){ System.out.println(status()); /* * 每一个打印以后,每一个线程都要睡眠(即阻塞),这使得线程调度器能够切换到另外一个线程,进而驱动另外一个任务 */ TimeUnit.MICROSECONDS.sleep(100000); } /* * 由于异常不能跨线程传回给main,因此你必须在线程里处理该异常 */ }catch(InterruptedException e){ System.out.println(); } } public static void main(String[] args){ ExecutorService exec = Executors.newCachedThreadPool(); for(int i = 0 ; i < 5 ; i++){ exec.execute(new TaskSleepingTask()); } exec.shutdown(); } }
可是,这不表明你就能够经过休眠的方式来保证任务的执行顺序(顺序行为依赖于底层的线程机制,这种机制在不一样的操做系统之间是有差别的
要想控制顺序的解决办法:一、同步控制,二、协做线程(之后再作序数)
2.优先级
优先级表明了该线程的重要性,线程调度器将倾向于让优先级高的线程先执行(但这不意味着优先权较低的线程将得不到执行,即优先权不会致使死锁)。优先级较低的线程仅仅是执行频率较低,在绝大多数时间里,全部线程都应该以默认优先级运行,试图操纵线程优先级一般是一种错误。
经过Thread.currentThread()方法来得到对驱动该任务的Thread对象的引用,而后设置线程优先级。
public class TaskPriority implements Runnable{ private int countDown = 5; /* * 变量d用来确保不进行任何编译器优化 */ @SuppressWarnings("unused") private volatile double d;//no optimization private int priority; public TaskPriority(int priority){ this.priority = priority; } /* * 打印线程的名称、线程的优先级以及线程所属的“线程组” *在线程内部,经过调用Thread.currentThread()来得到对驱动该任务的Thread对象的引用 */ public String toString(){ return Thread.currentThread()+":"+countDown; } @Override public void run() { /* * 优先级应该在run的开头部分设定,在构造器中设置他们不会有任何好处,由于Executor在此刻尚未开始执行任务 */ Thread.currentThread().setPriority(priority); /* * 执行了10000次浮点运算,数学 运算是能够中断的,这里运算时间足够长, * 所以线程调度机制才来得及介入,交换任务并关注优先级,使得最高优先级的线程被优先选择 */ while(true){ for(int i = 1 ;i < 10000;i++){ d+=(Math.PI + Math.E)/(double)i; if(i%1000==0) Thread.yield(); System.out.println(this); if(--countDown == 0 ) return; } } } public static void main(String[] args){ ExecutorService exec = Executors.newCachedThreadPool(); for(int i = 0 ; i < 5;i++){ exec.execute(new TaskPriority(Thread.MIN_PRIORITY));//1 } exec.execute(new TaskPriority(Thread.MAX_PRIORITY));//10 exec.shutdown(); } }
尽管jdk有10个优先级,可是它与多数操做系统都不能映射得很好(windows7个,solaris2个),惟一可移植的方法是当调整优先级的时候,只试用MAX_PRIORITY/NORM_PRIORITY/MIN_PRIORITY三种声明
3.让步
在你已经确认完成了在run方法的循环的一次迭代过程当中所需的工做,就能够给线程调度机制一个暗示:你的工做已经作的差很少了,可让别的线程试用cpu了。(让相同优先级的其余线程能够运行)。
java提供了调用yield()方法来实现。过这只是暗示没有任何机制保证它会被采纳,因此不能依赖该方法。如上例。