线程优先级
- 记住当线程的优先级没有指定时,所有线程都携带普通优先级。
- 优先级可以用从1到10的范围指定。10表示最高优先级,1表示最低优先级,5是普通优先级。
- 记住优先级最高的线程在执行时被给予优先。但是不能保证线程在启动时就进入运行状态。
- 与在线程池中等待运行机会的线程相比,当前正在运行的线程可能总是拥有更高的优先级。
- 由调度程序决定哪一个线程被执行。t.setPriority()用来设定线程的优先级。
- 记住在线程开始方法被调用之前,线程的优先级应该被设定。
- 你可以使用常量,如MIN_PRIORITY,MAX_PRIORITY,NORM_PRIORITY来设定优先级
- 线程的优先级可以被继承,并且如果父类的线程优先级改变,子类也随之改变。
public class Test165 {
public static void main(String[] args) {
System.out.println(Thread.currentThread().getPriority());
Thread.currentThread().setPriority(7);
Thread t = new Thread(new MyThread888());
t.start();
}
}
class MyThread909 extends Thread{
@Override
public void run() {
// TODO Auto-generated method stub
super.run();
System.out.println(Thread.currentThread().getPriority());
}
}
class MyThread888 extends Thread{
@Override
public void run() {
// TODO Auto-generated method stub
super.run();
System.out.println(Thread.currentThread().getPriority());
Thread t = new Thread(new MyThread909());
t.start();
}
}
在优先级不同的多个线程中,优先级高的线程得到的CPU资源多,优先级差距很大的时候,谁先执行完毕和代码调用顺序无关,也许优先级先执行,但是在整个执行过程中,优先级高的线程总是大部分先执行完毕,并不是优先级高的,就一下子全执行完毕。
参考:http://www.importnew.com/14958.html
sleep
在之前的博客中,已经讲了wait的知识点,而sleep和它差不多,都是让线程停下来,但是需要注意的是,wait必须给予同步代码块中,或者同步方法中,而sleep没有这个限制,最主要是wait方法执行了,线程会主动放弃持有的对象锁,而sleep方法执行,不会放弃持有的对象锁
yield
yield()方法的线程告诉虚拟机它乐意让其他线程占用自己的位置。这表明该线程没有在做一些紧急的事情。
- Yield告诉当前正在执行的线程把运行机会交给线程池中拥有相同优先级的线程,但是它不能保证让其他线程能立即获得cpu执行。
- Yield不能保证使得当前正在运行的线程迅速转换到可运行的状态,有可能它放弃了cpu执行权,但是下面获取的还是它。
- 它仅能使一个线程从运行状态转到可运行状态,而不是等待或阻塞状态(注意等待状态是不具有可运行的条件,阻塞状态是需要等待io的录入)
- Yield该方法是不会放弃对象锁的。所以要避免在同步中使用该方法,否则就没有意义。当然执行结束肯定会释放的了。
public static void main(String[] args) {
Thread t = new Thread(new MyThread999());
t.start();
}
}
class MyThread999 implements Runnable{
private int count;
@Override
public void run() {
// TODO Auto-generated method stub
long start = System.currentTimeMillis();
for(int i = 0;i<200000;i++) {
Thread.yield();
count+=i;
}
long end = System.currentTimeMillis();
System.out.println(end-start);
}
}
明显执行了yield方法,执行时间长。
例子
两线程交替来执行任务。
Thread t = new Thread(new Test125().new MyThread(lock));
Thread t1 = new Thread(new Test125().new MyThread(lock));
t.start();
t1.start();
}
class MyThread implements Runnable{
Object lock = null;
public MyThread(Object lock) {
super();
this.lock = lock;
}
@Override
public void run() {
// TODO Auto-generated method stub
synchronized (lock) {
for(int i =0;i<5;i++) {
System.out.println(Thread.currentThread().getName()+i);
}
Thread.yield();//让出该线程的执行权,给其他线程,同时释放对象锁
}
}
效果图
join
join方法的作用是父线程(main线程)等待子线程执行完成后再执行,换句话说就是将异步执行的线程合并为同步的线程
源码分析:
//这是从网上找到一小部分join源码,可以看到他主要使用了
wait方法,来阻塞当前对象的main(主线程),等待子线程执行完毕,方可执行主线程,这就是为什么将线程的异步并成同步的关键。
if (millis == 0) {
while (isAlive()) {
wait(0);
}
}
例子
MyTest m = new MyTest();
for(int i = 0;i<5;i++) {
Thread t = new Thread(m);
t.start();
try {
t.join();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
class MyTest implements Runnable{
@Override
public void run() {
// TODO Auto-generated method stub
System.out.println(Thread.currentThread().getName());
}
}
效果图:
如果没有的join方法,效果如下:线程是异步操作。
join(long time)
主线程阻塞这么长时间,如果子线程还没有完毕,那么主线程就不等了,拜拜!!!这个例子和join用法差不多,就不单独举例了。