Thread类中的方法调用方式
调用Thread中的方法的时候,在线程类中,有两种方式:
1.this.xxx()
这种方式的线程是线程实例本身。
2.Thread.currentThread.xxx()或Thread.xxx()
这种表示线程执行Thread.currenThread.xxx()所在代码块的线程。
Thread类的实例方法
1.start()
这个方法的作用就是通知线程规划器此现场可以运行了。要注意,调用start方法的顺序不代表线程启动的顺序,也就是cpu执行哪个线程的代码具有不确定性。。
2.run()
这个方法是线程类调用start后执行的方法,如果在直接调用run而不是start方法,那么和普通方法一样,没有区别。
3.isAlive()
是判断当前线程是否处于活动状态。活动状态就是已经启动尚未终止。
4.getPriority()和setPriority(int newPriority)
这两个方法是用于获取当前和设置线程的优先级。优先级高的线程得到的cpu多。也就是说,两个等待的线程,优先级高的线程容易被cpu执行。
默认情况下,线程的优先级是5。线程的优先级分为1~10等级。
优先级是具有继承性的:
1 public class MyThread1 extends Thread{ 2 public void run() { 3 System.out.println("MyThread1的线程优先级是"+this.getPriority()); 4 MyThread2 myThread2 = new MyThread2(); 5 myThread2.start(); 6 } 7 }
1 public class MyThread2 extends Thread{ 2 @Override 3 public void run() { 4 System.out.println("MyThread2的线程优先级是"+this.getPriority()); 5 } 6 }
1 public static void main(String[] args) { 2 System.out.println("main thread begin priority="+Thread.currentThread().getPriority()); 3 //Thread.currentThread().setPriority(6); 4 System.out.println("main thread end priority="+Thread.currentThread().getPriority()); 5 MyThread1 myThread1 = new MyThread1(); 6 myThread1.start(); 7 }
结果是
main thread begin priority=5 main thread end priority=5 MyThread1的线程优先级是5 MyThread2的线程优先级是5
把注释去掉再执行,结果是
main thread begin priority=5 main thread end priority=6 MyThread1的线程优先级是6 MyThread2的线程优先级是6
证明了线程优先级是具有继承性的。
5.isDaeMon、setDaemon(boolean on)
java线程有两种,一种是用户线程,一种是守护线程。守护线程是一个特殊的线程,任何一个守护线程都是jvm中所有非守护线程的保姆。当进程中不存在非守护线程时,守护线程会自动销毁。典型的守护线程就是垃圾回收线程。
第一个是判断线程是不是守护线程,第二个是设置线程为守护线程,必须在线程start之前setDaemon(true)。
6.interrupt()
使用这个方法并不会中断线程。实际上,调用interrupt实际作用是,在线程受到阻塞时抛出一个中断信号,这样线程就得以退出阻塞状态。
7.join()
1 public class MyThread1 extends Thread { 2 public void run() { 3 try { 4 int secondValue = (int) (Math.random() * 10000); 5 Thread.sleep(1000); 6 System.out.println(secondValue); 7 Thread.sleep(secondValue); 8 } catch (Exception e) { 9 e.printStackTrace(); 10 } 11 } 12 }
1 public static void main(String[] args) throws Exception { 2 MyThread1 myThread1 = new MyThread1(); 3 myThread1.start(); 4 //myThread1.join(); 5 System.out.println("main"); 6 }
结果是
main
6479
很明显是main方法先结束。那么去掉main中第4行的注释。结果是
7487
main
main晚于线程myThread1结束。
join方法会使得调用join方法的线程(myThread1线程)所在的线程(main线程)无限阻塞,直到调用join方法的线程销毁为止。也就是说,在这个例子当中,当myThread1线程销毁以后,main线程才会继续执行,在这期间都是阻塞的。
join方法内部使用的是wait(),所以会释放锁。
Thread类的静态方法
1.currentThread()
该方法返回的当前正在执行线程对象的引用。
1 public class MyThread1 extends Thread { 2 static { 3 System.out.println("静态块的打印:" + Thread.currentThread().getName()); 4 } 5 6 public MyThread1() { 7 System.out.println("构造方法的打印:" + Thread.currentThread().getName()); 8 } 9 10 public void run() { 11 System.out.println("run()方法的打印:" + Thread.currentThread().getName()); 12 } 13 }
1 public static void main(String[] args) throws Exception { 2 MyThread1 myThread1 = new MyThread1(); 3 myThread1.setName("myThread1"); 4 myThread1.start(); 5 }
结果
静态块的打印:main
构造方法的打印:main
run()方法的打印:myThread1
说明线程类的静态代码块,构造方法是被main线程调用的,run方法是线程自己调用的。
2.sleep(long millis)
sleep方法的作用就是在指定的时间让正在执行的线程休眠。并不释放锁。
3.yield()
暂停当前执行的线程对象,并执行其他线程。这个暂停会放弃cpu资源,放弃的时间不确定。
1 public class MyThread1 extends Thread { 2 3 public void run() { 4 long beginTime = System.currentTimeMillis(); 5 int count = 0; 6 for (int i = 0; i < 50000000; i++) 7 { 8 Thread.yield(); 9 count = count + i + 1; 10 } 11 long endTime = System.currentTimeMillis(); 12 System.out.println("用时:" + (endTime - beginTime) + "毫秒!"); 13 } 14 }
main
1 public static void main(String[] args) throws Exception { 2 MyThread1 myThread1 = new MyThread1(); 3 myThread1.setName("myThread1"); 4 myThread1.start(); 5 }
结果:第一次调用main
用时:4029毫秒!
结果:第二次调用main
用时:4030毫秒!
结果:第三次调用main
用时:4067毫秒!
每次执行main方法得到的结果基本不同,证明了yield放弃cpu的时间不确定。