多线程(5)- 控制线程

来源:互联网 发布:路由器和交换机 知乎 编辑:程序博客网 时间:2024/06/05 19:16

1.停止线程

如何停止线程?
只有一种方法,即让run方法结束。
开启多线程运行,运行代码通常是循环结构。所以只要控制住循环,就可以让run方法结束,也就是线程结束。

class StopThread implements Runnable{    private boolean flag =true;    public  void run()    {        while(flag)        {            System.out.println(Thread.currentThread().getName()+"....run");        }    }    public void changeFlag()    {        flag = false;    }}class  Test{    public static void main(String[] args)     {        StopThread st = new StopThread();        Thread t1 = new Thread(st);        Thread t2 = new Thread(st);        t1.start();        t2.start();        int num = 0;        while(true)        {            if(num++ == 60)            {                st.changeFlag();  //调用方法改变标志,结束run()方法                break;            }            System.out.println(Thread.currentThread().getName()+"......."+num);        }        System.out.println("over");    }}

特殊情况:
当线程处于了冻结状态(wait),就不会读取到标记,那么线程就不会结束。
当没有指定的方式让冻结的线程恢复到运行状态时,这时需要对冻结进行清除,强制让线程恢复到运行状态中来,这样就可以操作标记让线程结束。
Thread类提供该方法 interrupt()。

class StopThread implements Runnable{    private boolean flag =true;    public synchronized void run()    {        while(flag)        {            try{                wait();            }            catch(InterruptedException e){                System.out.println(Thread.currentThread().getName()+"....Exception");                flag = false;            }            System.out.println(Thread.currentThread().getName()+"....run");        }    }}class  Test{    public static void main(String[] args)     {        StopThread st = new StopThread();        Thread t1 = new Thread(st);        Thread t2 = new Thread(st);        t1.start();        t2.start();        int num = 0;        while(true)        {            if(num++ == 60)            {                t1.interrupt();                t2.interrupt();                break;            }            System.out.println(Thread.currentThread().getName()+"......."+num);        }        System.out.println("over");    }}

这里,线程1和2一执行就被wait(),主线程里达到停止条件num=60,是无法停止被冻结的线程1,2的。这里可以调用Thread类里的interrupt()方法,把线程的等待状态强制清除(被清除状态的线程会接收到一个InterruptedException异常),线程1,2得以继续执行,此时,标记被改变,run方法停止,线程停止。

2.守护线程

有一种线程,它是在后台运行的,它的任务是为其他的线程提供服务,它与被提供服务的线程存在依赖关系,这种线程叫做守护线程。如果所有的前台线程都死亡,守护线程会自动死亡。
JVM的垃圾回收线程就是典型的守护线程。
上面的例子中,如果加上

t1.setDaemon(true);t2.setDaemon(true);

就可以把线程1,2设置成主线程的守护线程,主线程结束,线程1,2就自动结束。

3.join方法

thread类中的join方法把指定的线程加入到当前线程,可以将两个交替执行的线程合并为顺序执行的线程。比如在线程B中调用了线程A的Join()方法,直到线程A执行完毕后,才会继续执行线程B。

t.join();      //使调用线程 t 在此之前执行完毕。t.join(1000);  //等待 t 线程,等待时间是1000毫秒

4.优先级

每个线程执行都有一定的优先级,优先级高的获得较多的执行机会,优先级低的获得较少执行机会。优先级分为10个等级,每个线程默认的优先级都与创建它的父进程优先级相同,默认情况下,main进程具有普通优先级,由main进程创建的子进程也具有普通优先级。
Thread类提供setPriority(int)和getPriority()来设置和返回线程的优先级,设置优先级可以是一个范围为1~10的整数,也可以使用Thread类的如下三个静态常量:
MAX_PRIORITY: 其值是10
MIN_PRIORITY: 其值是1
NORM_PRIORITY: 其值是5

5.线程让步

yield()方法是一个和sleep()方法有点类似的方法,它也是Thread类提供的一个静态方法,它可以让当前正在执行的线程暂停,但它不会阻塞该线程,它只是将该线程转入就绪状态。
yield()只是让当前线程暂停一下,让系统的线程调度器重新调度一次,完全可能的情况是:当某个线程调用了yield()方法暂停之后,线程调度器又将其调度出来重新执行。
实际上,当某个线程调用yield()方法暂停之后,只要优先级与当前线程相同,或者优先级比当前线程更高的处于就绪状态的线程才会获得执行的机会。

0 0