1.sleep()方法
●sleep()方法使线程由正在运行状态转换到阻塞状态;线程暂时放弃CPU使用权;
●sleep()方法是Thread类中的方法;
●public static void sleep(long millis):静态方法,可直接用Thread类名字去调用;millis:毫秒,1000ms == 1s;
●sleep()方法:应用场景可能有(1)需要计时的情况,每隔一定时间显示一下时间等;(2)对于一些需要定期刷新数据而不是一直刷新数据的情况;
●需要注意一个线程到底能不能执行,或者说一个线程到底能不能“暂停”,不仅和sleep()方法有关,还与CPU是否可用有关;当一个线程sleep()方法执行完毕后,线程只是进入了可运行状态,该线程必须获得CPU的使用权才能真正开始执行。(所以,sleep()方法应用在严格的时钟计算时,可能会存在误差);
……………………………………………………
示例程序:
注:sleep()方法需要捕获异常;
sleep()方法的具体应用场景和应用技巧需要在实际开发中慢慢积累;
class MyThread implements Runnable{
@Override
public void run() {
// TODO Auto-generated method stub
for(int i = 1;i<=15;i++){
System.out.println(Thread.currentThread().getName()+"执行第"+i+"次。");
try {
// 为什么要捕获异常:在线程执行sleep()方法时候,可能会因为某些原因线程突然被打断,要处理一下这种异常
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
public class SleepDemo {
public static void main(String[] args) {
// TODO Auto-generated method stub
MyThread mt = new MyThread();
Thread thread = new Thread(mt);
thread.start();
//Thread thread1 = new Thread(mt);
//thread1.start();
}
}
2.join方法
●join()方法使线程由正在运行状态转换到阻塞状态;线程暂时放弃CPU使用权;
●join()方法也是Thread类的方法;
●public final void join():是个final方法,字面理解join是加入、抢先进入的意思;
●一个线程调用了join()方法,那么这个线程获得了优先执行权,其他线程需要等待该线程执行完毕后才能执行;join()方法是一种抢占资源的方式;
……………………………………………………
示例程序:join(),无参形式,调用join()方法线程执行结束后,其他线程才会执行。
注:join()方法也需要捕获异常;
join()方法的具体应用场景和应用技巧需要在实际开发中慢慢积累;
class MyThread1 extends Thread{
public void run(){
for(int i = 1;i<=10;i++){
System.out.println(getName()+"正在执行"+i+"次。");
}
}
}
public class JoinDemo {
public static void main(String[] args) {
// TODO Auto-generated method stub
MyThread1 mt = new MyThread1();
mt.start();
try {
// 为什么要捕获异常:在线程执行join()方法时候,可能会因为某些原因线程突然被打断,要处理一下这种异常
mt.join();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
for(int i = 1;i<=10;i++){
System.out.println("主线程运行第"+i+"次。");
}
System.out.println("主线程运行结束。");
}
}
输出结果:可以发现,因为mt线程调用了join()方法,所以mt线程获得了优先执行权;
Thread-0正在执行1次。
Thread-0正在执行2次。
Thread-0正在执行3次。
Thread-0正在执行4次。
Thread-0正在执行5次。
Thread-0正在执行6次。
Thread-0正在执行7次。
Thread-0正在执行8次。
Thread-0正在执行9次。
Thread-0正在执行10次。
主线程运行第1次。
主线程运行第2次。
主线程运行第3次。
主线程运行第4次。
主线程运行第5次。
主线程运行第6次。
主线程运行第7次。
主线程运行第8次。
主线程运行第9次。
主线程运行第10次。
主线程运行结束。
若是,mt线程没有调用join方法:
class MyThread1 extends Thread{
public void run(){
for(int i = 1;i<=10;i++){
System.out.println(getName()+"正在执行"+i+"次。");
}
}
}
public class JoinDemo {
public static void main(String[] args) {
// TODO Auto-generated method stub
MyThread1 mt = new MyThread1();
mt.start();
// try {
// // 为什么要捕获异常:在线程执行join()方法时候,可能会因为某些原因线程突然被打断,要处理一下这种异常
// mt.join();
// } catch (InterruptedException e) {
// // TODO Auto-generated catch block
// e.printStackTrace();
// }
for(int i = 1;i<=10;i++){
System.out.println("主线程运行第"+i+"次。");
}
System.out.println("主线程运行结束。");
}
}
输出结果:mt线程没有调用join()方法时,mt线程和主线程随机获取CPU使用权。
主线程运行第1次。
Thread-0正在执行1次。
主线程运行第2次。
Thread-0正在执行2次。
主线程运行第3次。
Thread-0正在执行3次。
Thread-0正在执行4次。
主线程运行第4次。
主线程运行第5次。
主线程运行第6次。
主线程运行第7次。
主线程运行第8次。
主线程运行第9次。
主线程运行第10次。
主线程运行结束。
Thread-0正在执行5次。
Thread-0正在执行6次。
Thread-0正在执行7次。
Thread-0正在执行8次。
Thread-0正在执行9次。
Thread-0正在执行10次。
……………………………………………………
示例程序:join(long millis):调用join(long millis)方法的线程,其优先执行权只能维持一定时间,一定时间过后丧失优先权,和其他线程一样随机获取执行权
class MyThread1 extends Thread{
public void run(){
for(int i = 1;i<=300;i++){
System.out.println(getName()+"正在执行"+i+"次。");
}
}
}
public class JoinDemo {
public static void main(String[] args) {
// TODO Auto-generated method stub
MyThread1 mt = new MyThread1();
mt.start();
try {
// 为什么要捕获异常:在线程执行join()方法时候,可能会因为某些原因线程突然被打断,要处理一下这种异常
mt.join(2);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
for(int i = 1;i<=10;i++){
System.out.println("主线程运行第"+i+"次。");
}
System.out.println("主线程运行结束。");
}
}
输出结果:输出结果截取部分,由执行结果可以发现join(long millis)方法作用。
Thread-0正在执行66次。
Thread-0正在执行67次。
Thread-0正在执行68次。
Thread-0正在执行69次。
主线程运行第1次。
Thread-0正在执行70次。
Thread-0正在执行71次。
主线程运行第2次。
Thread-0正在执行72次。
主线程运行第3次。
Thread-0正在执行73次。
主线程运行第4次。
Thread-0正在执行74次。
主线程运行第5次。
Thread-0正在执行75次。
主线程运行第6次。
Thread-0正在执行76次。
主线程运行第7次。
Thread-0正在执行77次。
主线程运行第8次。
Thread-0正在执行78次。
Thread-0正在执行79次。
Thread-0正在执行80次。
Thread-0正在执行81次。
Thread-0正在执行82次。
Thread-0正在执行83次。
Thread-0正在执行84次。
Thread-0正在执行85次。
Thread-0正在执行86次。
3.线程的优先级
●Java为线程提供了10个优先级,优先级可以使用整数1-10表示,超过这个范围会抛出异常;数字越大,表示优先级越高;
●main()方法的线程(主线程)默认优先级是5;
●除了用数字表示优先级,还可以用优先级常量来表示优先级:
MAX_PRIORITY:线程的最高优先级10;
MIN_PRIORITY:线程的最低优先级1;
NORM_PRIORITY:线程的默认优先级5;
●Thread类提供了获取线程优先级的方法、和设置线程优先级的方法:
●线程的优先级只是提供了一个优先级别,优先级高的线程不一定非得先执行,是否先执行与CPU状态,系统状态等很多因素有关;即其执行还是有一定的随机性的;
……………………………………………………
示例程序:主要就是setPriority()方法、和getPriority()方法;
class MyThread2 extends Thread{
private String name;
public MyThread2(){}
public MyThread2(String name){
// 注:给线程自定义名字,需要调用Thread的有参构造才行,即需要super(name)才行;
// 这儿的name只是一个方便观察的变量,其实并不是线程的name.
this.name = name;
}
public void run(){
for(int i = 1;i<=10;i++){
System.out.println("线程"+name+"正在执行"+i);
}
}
}
public class PriorityDemo {
public static void main(String[] args) {
// 获取主线程的优先级
int mainPriority = Thread.currentThread().getPriority();
//System.out.println("主线程的优先级为:"+mainPriority);
MyThread2 mt1 = new MyThread2("线程1");
MyThread2 mt2 = new MyThread2("线程2");
int mt1Priority = mt1.getPriority();
//System.out.println("mt1线程的优先级为:"+mt1Priority);
// 设置mt1线程的优先级
//mt1.setPriority(10);
//或者这样设置mt1的优先级
mt1.setPriority(Thread.MAX_PRIORITY);
mt2.setPriority(Thread.MIN_PRIORITY);
mt1.start();
mt2.start();
}
}
输出结果:可以发现,并不是高优先级的线程先执行完后低优先级的线程才执行,其任然存在一定的随机性;
换句话说,优先级高的程序并不一定会比优先级低的线程先运行;
线程线程1正在执行1
线程线程2正在执行1
线程线程1正在执行2
线程线程2正在执行2
线程线程1正在执行3
线程线程2正在执行3
线程线程1正在执行4
线程线程1正在执行5
线程线程1正在执行6
线程线程1正在执行7
线程线程1正在执行8
线程线程1正在执行9
线程线程1正在执行10
线程线程2正在执行4
线程线程2正在执行5
线程线程2正在执行6
线程线程2正在执行7
线程线程2正在执行8
线程线程2正在执行9
线程线程2正在执行10