线程优先级priority
再次强调一点:线程的优先级的高低并不代表执行的先后顺序,线程执行的先后顺序是由JVM决定的。
package ThreadStudy;
public class PriorityTest {
public static void main(String[] args) {
System.out.println(Thread.currentThread().getPriority());
Test test = new Test();
Thread t1 = new Thread(test,"t1");
Thread t2 = new Thread(test,"t2");
Thread t3 = new Thread(test,"t3");
Thread t4 = new Thread(test,"t4");
Thread t5 = new Thread(test,"t5");
t1.setPriority(Thread.MAX_PRIORITY);
t2.setPriority(Thread.MAX_PRIORITY);
t3.setPriority(Thread.NORM_PRIORITY);
t4.setPriority(Thread.MIN_PRIORITY);
t5.setPriority(Thread.MIN_PRIORITY);
t1.start();
t2.start();
t3.start();
t4.start();
t5.start();
}
}
class Test implements Runnable {
@Override
public void run() {
System.out.println(Thread.currentThread().getName()+"->"+Thread.currentThread().getPriority());
}
}
运行结果:
守护线程
守护线程是为用户线程服务的,例如后台记录操作日志的线程,监控内存的线程。
虚拟机只看用户线程的脸色,不看守护线程的脸色,虚拟机必须确保所有用户线程执行完毕才会停止,而不用等待守护线程执行完毕。
package ThreadStudy;
public class DaemonTest {
public static void main(String[] args) {
Log log = new Log();
User user = new User();
Thread t1 = new Thread(log);
Thread t2 = new Thread(user);
t1.setDaemon(true);
t1.start();
t2.start();
}
}
class Log implements Runnable {
@Override
public void run() {
while (true) {
System.out.println("正在记录日志........");
}
}
}
class User implements Runnable {
@Override
public void run() {
for (int i = 0; i < 7; i++) {
System.out.println("用户的第"+i+"次操作");
}
}
}
运行结果:
可以看到,把Log对象的线程设置成了守护线程,并且这个守护线程里面是死循环,所以自己不会停止,正好说明了JVM不会等待守护线程执行结束,用户线程结束后就停止了程序。
常用的线程方法
package ThreadStudy02;
public class InfoTest {
public static void main(String[] args) {
MyThread myThread = new MyThread("我的线程");
Thread t = new Thread(myThread);
t.start();
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(t.isAlive());
}
}
class MyThread implements Runnable {
private String name;
public MyThread(String name) {
this.name = name;
}
@Override
public void run() {
System.out.println(Thread.currentThread().getName()+"--->"+name);
}
}
运行结果:
如果把t.setName(“你的线程”);取消注释:
可以看见,两次运行的区别就是用户线程的真实名称被修改了。
在实例化线程类MyThread的时候,传递的字符串参数被构造器使用,实例化一个线程对象的时候给这个线程取了一个代理名称,而调用setName()是设置这个线程的真实名称。
|