JAVA线程的调度

终止线程:
正确的终止一个线程的方法,应当是设置一个供线程定期检查的变量,当线程检查到这个变量的状态发生改变时,则从 run() 方法返回。
Thread.suspend() 和 Thread.stop() 提供了异步方法终止一个线程,然而,由于这些方法是不安全的,因此,已被废弃。使用它们经常导致死锁或不正确的资源释放。
当线程抛出一个未捕获到的 Exception 或 Error 时,也会导致线程终止。
--------------------------------------------------------------------------------

    // 创建并启动一个线程
    MyThread thread = new MyThread();
    thread.start();
    
    // do something...
    
    // 终止线程
    thread.allDone = true;


  -------------------------------------------------------------------------------- 

 

   class MyThread extends Thread {
        boolean allDone = false;
    
        // 这个方法当线程启动时得到调用
        public void run() {
            while (true) {
                // do something...
    
                if (allDone) {
                    return;
                }
                // do something...
            }
        }
    }
 

加入线程:Thread API 包含了等待另一个线程完成的方法:join() 方法。当调用 Thread.join() 时,调用线程将阻塞,直到目标线程完成为止。
Thread.join() 通常由使用线程的程序使用,以将大问题划分成许多小问题,每个小问题分配一个线程。

 

调度:
除了何时使用 Thread.join() 和 Object.wait() 外,线程调度和执行的计时是不确定的。如果两个线程同时运行,而且都不等待,您必须假设在任何两个指令之间,其它线程都可以运行并修改程序变量。如果线程要访问其它线程可以看见的变量,如从静态字段(全局变量)直接或间接引用的数据,则必须使用同步以确保数据一致性。
在以下的简单示例中,我们将创建并启动两个线程,每个线程都打印两行到 System.out:

public class TwoThreads {
        public static class Thread1 extends Thread {
                public void run() {
                        System.out.println("A");
                        System.out.println("B");
                }
        }
        public static class Thread2 extends Thread {
                public void run() {
                        System.out.println("1");
                        System.out.println("2");
                }
        }
        public static void main(String[] args) {
                new Thread1().start();
                new Thread2().start();
        }
}


以上这段代码,我们并不知道这些行按什么顺序执行,只知道“1”在“2”之前打印,以及“A”在“B”之前打印。输出可能是以下结果中的任何一种:
        1 2 A B
        1 A 2 B
        1 A B 2
        A 1 2 B
        A 1 B 2
        A B 1 2

 

休眠:Thread API 包含了一个 sleep() 方法,它将使当前线程进入等待状态,直到过了一段指定时间,或者直到另一个线程对当前线程的Thread 对象调用了 Thread.interrupt(),从而中断了线程。当过了指定时间后,线程又将变成可运行的,并且回到调度程序的可运行线程队列中。
如果线程是由对 Thread.interrupt() 的调用而中断的,那么休眠的线程会抛出InterruptedException,这样线程就知道它是由中断唤醒的,就不必查看计时器是否过期。Thread.yield() 方法就象 Thread.sleep() 一样,但它并不引起休眠,而只是暂停当前线程片刻,这样其它线程就可以运行了。在大多数实现中,当较高优先级的线程调用Thread.yield() 时,较低优先级的线程就不会运行。

守护线程:一个守护线程的唯一作用就是为其他线程提供服务。如计时器线程,隐藏的系统线程(如垃圾收集线程和由 JVM 创建的其它线程)等都属于守护线程。
可以通过调用Thread.setDaemon(boolean isDaemon) 方法来指明某个线程是守护程序线程。这个方法必须在线程开始之前调用。

线程状态:线程可以有以下四个状态
新生线程(New):用new操作符创建一个线程时,线程还没有开始运行,此时线程处在新生状态。
可运行线程(Runnable):当调用了start()方法后,线程即变为可运行的了。一个可运行线程可能正在运行,也可能没有,这取决于操作系统为该线程提供的运行时间。这正是为什么把这种状态称为runnable而不是running。
被阻塞线程(Blocked):当发生以下任何一种情况时,线程就进入被阻塞状态。
        线程通过调用sleep方法进入睡眠状态
        线程调用一个在I/O上被阻塞的操作,即该操作在输入输出操作完成之前不会返回给他的调用者
        线程试图得到一个锁,而该锁正在被其他线程持有
        线程在等待某个触发条件
        有人调用了线程的suspend方法(该方法已被废弃,不应再使用)
死线程(Dead):有两个原因会导致线程死亡。
        因为run方法正常退出而自然死亡
        因为一个未捕获的异常终止了run方法而使线程猝死
    特殊情况下,可以调用线程的stop方法来终止一个线程,这个方法抛出一个ThreadDeath出错对象来杀死线程。但是这个方法已作废,不应再使用。为了确定线程是否存活,可以使用isAlive方法进行判断,当线程是可运行或是被阻塞的,这个方法返回true,否则返回false。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值