线程Thread类中的常用方法讲解

1、start() 方法:使一个线程启动,并执行该线程对应的run()方法
说明:
> 线程只能启动一次,一旦线程启动了,再次启动会抛出java.lang.IllegalThreadStateException异常
package org.xyz.java.thread.demo02;
/**
 * 线程的start方法讲解
 * @author kevin.chen
 *
 */
public class StartMethod {
        
        public static void main(String[] args) {
        // 使用匿名内部类,实现Runnable接口的方式来创建线程
        Thread t = new Thread(new Runnable() {
                @Override
                public void run() {
                        for(int i = 0;i < 10; i++) {
                                System.out.println(Thread.currentThread().getName() + "-run: "+ i);
                        }
                }
                
        });
        
        // 在主线程中重新启动了一个新的线程,新的线程会执行run()方法(线程名为:Thread-0)
        t.start();
        
        // 主线程继续循环操作(线程名为:main)
        for(int i = 0;i < 10; i++) {
                System.out.println(Thread.currentThread().getName() + "-main: "+ i);
        }
        
        // 再次调用一个启动过的线程,会抛出java.lang.IllegalThreadStateException异常
        t.start();
        
        }
}
运行结果:2个线程输出顺序是无序的,交错抢占cpu资源
main-main: 0
Thread-0-run: 0
main-main: 1
Thread-0-run: 1
main-main: 2
Thread-0-run: 2
main-main: 3
Thread-0-run: 3
main-main: 4
Thread-0-run: 4
main-main: 5
Thread-0-run: 5
main-main: 6
Thread-0-run: 6
main-main: 7
Thread-0-run: 7
Thread-0-run: 8
Thread-0-run: 9
main-main: 8
main-main: 9
Exception in thread "main" java.lang.IllegalThreadStateException
        at java.lang.Thread.start(Thread.java:708)
        at org.xyz.java.thread.demo02.StartMethod.main(StartMethod.java:31)
> 启动线程是调用start(),而不是run()方法。
> 调用start()方法是在当前线程中重新启动一个新线程,之后会调用线程对象的run()方法;
> 而调用run()相当于调用对象的一个普通方法,不会启动线程,其执行的线程还是当前线程中执行

对比上面和下面的代码可以看出端倪:

package org.xyz.java.thread.demo02;
/**
 * 线程的start方法讲解
 * @author kevin.chen
 *
 */
public class StartMethod {
        
        public static void main(String[] args) {
                // 使用匿名内部类,实现Runnable接口的方式来创建线程
                Thread t = new Thread(new Runnable() {
                        @Override
                        public void run() {
                                for(int i = 0;i < 10; i++) {
                                        System.out.println(Thread.currentThread().getName() + "-run: "+ i);
                                }
                        }
                        
                });
                
                // 在主线程中不会重新启动一个新的线程,只是调用类的普通方法,此时还是在主线程中(线程名为:main)
                t.run();
                
                // 而且,此时必须要等到上面的方法执行完之后再执行循环操作(线程名为:main)
                for(int i = 0;i < 10; i++) {
                        System.out.println(Thread.currentThread().getName() + "-main: "+ i);
                }
                
        }
}
运行结果:只有主线程一个线程,run方法是对象的一个普通方法,不会创建新的线程来执行,依旧在主线程中执行,run()方法执行后才会继续下面的代码
main-run方法: 0
main-run方法: 1
main-run方法: 2
main-run方法: 3
main-run方法: 4
main-run方法: 5
main-run方法: 6
main-run方法: 7
main-run方法: 8
main-run方法: 9
main-main方法: 0
main-main方法: 1
main-main方法: 2
main-main方法: 3
main-main方法: 4
main-main方法: 5
main-main方法: 6
main-main方法: 7
main-main方法: 8
main-main方法: 9
2、sleep() 方法:在指定的毫秒数内让当前正在执行的线程休眠(暂停执行)
说明:
> 如果sleep方法在同步方法或同步代码块中调用,那么该线程在睡眠的过程中是不会释放同步锁的
> 线程的状态由之前的运行状态转换为超时等待状态,睡眠时间到后,线程状态由超时等待转换为可运行状态,重新抢占cpu的资源。
package org.xyz.java.thread.demo02;
/**
 * 线程的sleep方法讲解 
 *   在指定的毫秒数内让当前正在执行的线程休眠(暂停执行)
 * @author kevin.chen
 *
 */
public class SleepMethod {
        public static void main(String[] args) {
                sleepTest();
        }
        
        public static void sleepTest() {
                Thread t = new Thread(new Runnable() {
                        @Override
                        public void run() {
                                for(int i = 0; i< 10; i++) {
                                        try {
                                                // 调用sleep方法,让线程休眠100毫秒
                                                Thread.sleep(100);
                                        } catch (InterruptedException e) {
                                                e.printStackTrace();
                                        }
                                        System.out.println(Thread.currentThread().getName() + ": " + i);
                                }
                        }
                        
                });
                
                t.start();
        }
}
3、join() 方法:将一个线程加入到另一个线程之前进行执行,直到加入的线程死亡。
说明:该方法有三个实现
> join() 无参的情况是加入的线程先执行完(cpu优先使用权)后再执行被加入的线程程序代码
> join(long millis) 该线程在加入指定的<毫秒>数之后和被加入的线程同时抢占cpu资源
> join(long millis,int nanos) 该线程在加入指定的<毫秒+纳秒>数之后和被加入的线程同时抢占cpu资源
> 不调 join 的情况
package org.xyz.java.thread.demo02;
/**
 * 线程的join方法讲解 
 *   在一个线程中调用另一个线程的join方法,当前线程释放cpu使用权会挂起,join进来的线程先执行,执行完之后,被join的线程再继续执行。
 * @author kevin.chen
 *
 */
public class JoinMethod {
        public static void main(String[] args) {
                for(int i = 0; i < 10; i++) {
                        // 当主线程执行2次的时候,将另外一个新的线程join进来
                        if( i == 2) {
                                Thread t = new Thread(new Runnable() {
                                        @Override
                                        public void run() {
                                                for(int i = 10; i < 20; i++) {
                                                        System.out.println(Thread.currentThread().getName() + ": " + i);
                                                }
                                        }
                                        
                                });
                                t.start();
                        }
                        System.out.println(Thread.currentThread().getName() + ": " + i);
                }
        }
}
> 运行结果:
main: 0
main: 1
main: 2
main: 3
main: 4
main: 5
Thread-0: 10
main: 6
Thread-0: 11
Thread-0: 12
Thread-0: 13
Thread-0: 14
Thread-0: 15
main: 7
Thread-0: 16
main: 8
Thread-0: 17
main: 9
Thread-0: 18
Thread-0: 19
> 调用 join 的情况:
package org.xyz.java.thread.demo02;
/**
 * 线程的join方法讲解 
 *   在一个线程中调用另一个线程的join方法,当前线程释放cpu使用权会挂起,join进来的线程先执行,执行完之后,被join的线程再继续执行。
 * @author kevin.chen
 *
 */
public class JoinMethod {
        public static void main(String[] args) {
                for(int i = 0; i < 10; i++) {
                        // 当主线程执行2次的时候,将另外一个新的线程join进来
                        if( i == 2) {
                                Thread t = new Thread(new Runnable() {
                                        @Override
                                        public void run() {
                                                for(int i = 10; i < 20; i++) {
                                                        System.out.println(Thread.currentThread().getName() + ": " + i);
                                                }
                                        }
                                        
                                });
                                t.start();
                                try {
                                        // 线程的join()方法是会让被join的线程进入到阻塞状态,只有join的线程执行完毕之后才会继续执行下去
                                        t.join();
                                } catch (InterruptedException e) {
                                        e.printStackTrace();
                                }
                        }
                        System.out.println(Thread.currentThread().getName() + ": " + i);
                }
        }
}
> 运行结果:
main: 0
main: 1
Thread-0: 10
Thread-0: 11
Thread-0: 12
Thread-0: 13
Thread-0: 14
Thread-0: 15
Thread-0: 16
Thread-0: 17
Thread-0: 18
Thread-0: 19
main: 2
main: 3
main: 4
main: 5
main: 6
main: 7
main: 8
main: 9
4、yield() 方法:释放当前线程的cpu使用权
说明:
>线程释放cpu的使用权,不代表线程不再执行,释放cpu使用权的瞬间可能有抢占了cpu的使用权
package org.xyz.java.thread.demo02;
/**
 * 线程的yield方法讲解 
 *   在一个线程中调用yield方法,当前线程会释放cpu使用权,线程状态从运行态转换为可运行态,和其他线程抢占cpu的使用权
 * @author kevin.chen
 *
 */
public class YieldMethod {
        public static void main(String[] args) {
                // 子线程
                Thread t = new Thread(new Runnable() {
                        @Override
                        public void run() {
                                for(int i = 10; i < 20; i++) {
                                        if(i > 15) {
                                                // 让当前线程释放cpu的使用权
                                                Thread.yield();
                                        }
                                        System.out.println(Thread.currentThread().getName() + ": " + i);
                                }
                        }
                        
                });
                t.start();
                // 主线程
                for(int i = 0; i < 10; i++) {
                        System.out.println(Thread.currentThread().getName() + ": " + i);
                }
        }
}
5、setPriority() 方法:设置线程的优先级
说明:
> 线程的优先级有1~10个等级值可供设置,1为优先级最低,10为优先级最高,默认不设置线程的优先级为5,如果父类线程设置了优先级,而子线程没有设置,那么子线程会继承父线程的优先级
> 优先级高的线程对抢占cpu的概率要大于优先级低的线程,但并不代表优先级高的线程一定先于优先级低的线程执行。
package org.xyz.java.thread.demo02;
/**
 * 线程的setPriority方法、getPriority方法讲解 
 *   给一个线程设置优先级,优先级的值取值范围为1~10,取值越大,线程优先级越高,线程默认值为5
 * @author kevin.chen
 *
 */
public class PriorityMethod {
        public static void main(String[] args) {
                Thread t1 = new Thread(new Runnable() {
                        @Override
                        public void run() {
                                for(int i=0; i< 10; i++) {
                                        System.out.println(Thread.currentThread().getName() + "的优先级为: " + Thread.currentThread().getPriority());					
                                }
                        }});
                
                t1.setName("线程<1>");
                
                Thread t2 = new Thread(new Runnable() {
                        @Override
                        public void run() {
                                for(int i=0; i< 10; i++) {
                                        System.out.println(Thread.currentThread().getName() + "的优先级为: " + Thread.currentThread().getPriority());					
                                }
                        }});
                
                t2.setName("线程[2]");
                t2.setPriority(Thread.MAX_PRIORITY); // 最大优先级
                
                Thread t3 = new Thread(new Runnable() {
                        @Override
                        public void run() {
                                for(int i=0; i< 10; i++) {
                                        System.out.println(Thread.currentThread().getName() + "的优先级为: " + Thread.currentThread().getPriority());					
                                }
                        }});
                
                t3.setName("线程(3)");
                t3.setPriority(Thread.MIN_PRIORITY);// 最小优先级
                
                t1.start();
                t2.start();
                t3.start();
        }
}
运行结果:优先级越高,优先执行的机会越大,但不是一定优先级高的比优先级低先执行。
线程[2]的优先级为: 10
线程(3)的优先级为: 1
线程<1>的优先级为: 5
线程<1>的优先级为: 5
线程<1>的优先级为: 5
线程<1>的优先级为: 5
线程[2]的优先级为: 10
线程[2]的优先级为: 10
线程[2]的优先级为: 10
线程[2]的优先级为: 10
线程[2]的优先级为: 10
线程[2]的优先级为: 10
线程(3)的优先级为: 1
线程<1>的优先级为: 5
线程<1>的优先级为: 5
线程<1>的优先级为: 5
线程(3)的优先级为: 1
线程[2]的优先级为: 10
线程(3)的优先级为: 1
线程<1>的优先级为: 5
线程<1>的优先级为: 5
线程(3)的优先级为: 1
线程[2]的优先级为: 10
线程(3)的优先级为: 1
线程<1>的优先级为: 5
线程(3)的优先级为: 1
线程[2]的优先级为: 10
线程(3)的优先级为: 1
线程(3)的优先级为: 1
线程(3)的优先级为: 1
6、interrupt() 方法:让当前线程挂起
说明:
> 通过isInterrupt()方法来判断方法当前线程是否为挂起等待,不要以为它是中断某个线程!它只是线线程发送一个中断信号,让线程在无限等待时(如死锁时)能抛出抛出,从而结束线程,但是如果你吃掉了这个异常,那么这个线程还是不会中断的!
package org.xyz.java.thread.demo02;
/**
 * 线程的interrupt方法讲解 
 *   不要以为它是中断某个线程!它只是线线程发送一个中断信号,让线程在无限等待时(如死锁时)能抛出抛出,从而结束线程,但是如果你吃掉了这个异常,那么这个线程还是不会中断的!
 * @author kevin.chen
 *
 */
public class InterruptMethod {
        public static void main(String[] args) {
                Thread t = new Thread(new Runnable() {
                        @Override
                        public void run() {
                                System.out.println(Thread.currentThread().getName());
                        }});
                // 启动线程
                t.start();
                
                boolean b = t.isInterrupted();
                System.out.println("检查线程启动后是否为挂起状态:" + b);
                
                // 让子线程挂起
                t.interrupt();
                
                b = t.isInterrupted();
                System.out.println("检查线程挂起后是否为挂起状态:" + b);
                
        }
}
7、currentThread() 方法:获取当前线程实例对象
8、setName() 方法:设置线程的名称
9、isAlive() 方法:判断当前线程是否存活,如果是,返回true; 否则,返回false。
10、isDeamon() 方法:判断当前线程是否是主线程,如果是,返回true; 否则,返回false。
11、stop() 方法:使线程停止
    说明:已过时,该方法可能会导致死锁
12、destroy() 方法:使线程销毁
    说明: 已过时,该方法可能会导致死锁
13、suspend() 方法:让线程挂起
    说明:已过时,该方法可能会导致死锁
14、resume() 方法:让线程恢复运行
    说明: 已过时,该方法可能会导致死锁
package org.xyz.java.thread.demo02;

public class OtherMethod {
        public static void main(String[] args) {
                Thread t = new Thread(new Runnable() {
                        @Override
                        public void run() {
                                System.out.println("线程其他方法使用...");
                                try {
                                        Thread.sleep(2000);
                                } catch (InterruptedException e) {
                                        e.printStackTrace();
                                }
                        }
                        
                });
                
                t.start();
                
                try {
                        Thread.sleep(1000);
                        // 判断线程是否存活
                        isAliveMethod(t);
                        // 判断线程是否为主线程
                        isDaemonMethod(t);
                        Thread.sleep(1000);
                } catch (InterruptedException e) {
                        e.printStackTrace();
                }
                
                // 挂起操作
                suspendMethod(t);
                System.out.println("线程已经挂起");
                // 恢复操作
                resumeMethod(t);
                System.out.println("线程已经恢复");
                // 停止操作
                stopMethod(t);
                System.out.println("线程已经停止");
                // 销毁操作
                // destroyMethod(t);
                System.out.println("线程已经销毁");
                
                // 再次判断线程是否存活
                isAliveMethod(t);
        }
        
        // 线程isAlive方法使用
        public static void isAliveMethod(Thread thread) {
                boolean b = thread.isAlive();
                System.out.println("当前线程存活状态:" + b);
        }
        
        // 线程suspend方法使用
        public static void isDaemonMethod(Thread thread) {
                boolean b = thread.isDaemon();
                System.out.println("当前线程是否为主线程:" + b);
        }
        
        // 线程suspend方法使用
        public static void suspendMethod(Thread thread) {
                thread.suspend();
        }
        
        // 线程resume方法使用
        public static void resumeMethod(Thread thread) {
                thread.resume();
        }
        
        // 线程stop方法使用
        public static void stopMethod(Thread thread) {
                thread.stop();
        }
                
        // 线程destroy方法使用
        public static void destroyMethod(Thread thread) {
                thread.destroy();
        }
}
运行结果: destroy() 方法会报 java.lang.NoSuchMethodError 错误,这里暂时屏蔽掉
线程其他方法使用...
当前线程存活状态:true
当前线程是否为主线程:false
线程已经挂起
线程已经恢复
线程已经停止
线程已经销毁
当前线程存活状态:false
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值