基本的线程机制(三)

4.休眠
       对于休眠我们这里会详细讨论sleep()方法和yield()方法,wait()方法暂时不讨论.
       Thread.sleep():

public static native void sleep(long millis) throws InterruptedException;

是Thread类中的一个静态方法,该方法会让当前正在执行的线程暂停执行,从而将执行机会让给其他线程执行。sleep中的参数指定当前线程暂停的时间,经过这段阻塞时间后,线程会进入就绪状态,等候线程的调度器的调用。sleep方法申明抛出InterruptedException异常,这个异常不会被抛到main方法中所以要在run中捕获。
       yield()方法只会给优先级相同或更高优先级的线程执行机会。yield不会讲线程转入阻塞状态,只是强制当前线程进入就绪状态。因此完全有可能某个线程调用yield方法暂停后,立即又获得处理器资源被执行。在这里特别注意,通常不要依靠yield控制并发
5.优先级
       线程的优先级将该线程的重要性传递给了调度器。尽管cpu处理现有的进程集的顺序是不确定的,但是调度器将倾向于让优先权高的线程先执行。然而,这并不是意味着优先权较低的线程将得不到执行(注意:优先权不会导致死锁)。优先权较低的线程仅仅是执行的频率较低。
在大多数时间里,线程都应该以默认的优先级运行。改变优先级通常是一种错误。
JDK中有10个优先级,但它与多数操作系统都不能映射得很好。所以我们一般只使用MAX_PRIORITY,NORM_PRIORITY,MIN_PRIORITY三种级别
6.让步
       如果知道已经完成了run()方法的循环的一次迭代过程中所需的工作,就可以给线程调度机制一个暗示:你的工作已经做得差不多了,可以让别的线程使用CPU了。这个暗示将通过调用yield()方法来作出(不过这只是一个暗示,没有任何机制保证它将会被采纳)。当调用yield()时,你也是在建议具有相同优先级的其他线程可以运行。
7.后台线程
       所谓后台线程,是指在程序运行的时候在后台提供一种通用服务的线程,并且这种线程并不属于程序中不可或缺的部分。因此,当所有的非后台线程结束时,程序也就终止了,同时会杀死进程中的所有后台进程。
       举个例子说:main线程就是一个非后台线程

public class SimpleDaemons implements Runnable{
    @Override
    public void run() {
        try {
            TimeUnit.MILLISECONDS.sleep(100);
            System.out.println(Thread.currentThread()+" " +this);
        } catch (InterruptedException e) {
            System.out.println("sleep() interrupted");
        }
    }
    public static void main(String[] args) throws Exception{
        for (int i = 0; i < 10; i++) {
            Thread daemon=new Thread(new SimpleDaemons());
            daemon.setDaemon(true);
            daemon.start();
        }
        System.out.println("All daemons started");
        TimeUnit.MILLISECONDS.sleep(175);
    }

}/* All daemons started Thread[Thread-7,5,main] com.lz.concurrency.SimpleDaemons@22dd0f87 Thread[Thread-9,5,main] com.lz.concurrency.SimpleDaemons@21c55e69 Thread[Thread-1,5,main] com.lz.concurrency.SimpleDaemons@356f5b17 Thread[Thread-3,5,main] com.lz.concurrency.SimpleDaemons@24b950d1 Thread[Thread-6,5,main] com.lz.concurrency.SimpleDaemons@67a9b034 Thread[Thread-0,5,main] com.lz.concurrency.SimpleDaemons@64889c4e Thread[Thread-2,5,main] com.lz.concurrency.SimpleDaemons@5f2679f2 Thread[Thread-5,5,main] com.lz.concurrency.SimpleDaemons@57102fab Thread[Thread-8,5,main] com.lz.concurrency.SimpleDaemons@324f0f97 Thread[Thread-4,5,main] com.lz.concurrency.SimpleDaemons@268dc2d */

       对于这段代码我们特别关注setDaemon方法:
1. setDaemon需要在start方法调用之前使用
2. 线程划分为用户线程和后台(daemon)线程,setDaemon将线程设置为后台进程
3. 如果jvm中都是后台线程,当前jvm将exit。(随之而来的,所有的一切烟消云散,包括后台线程啦)
4. 主线程结束后,
1) 用户线程将会继续运行
2) 如果没有用户线程,都是后台线程的话,那么jvm结束
在这段代码中我们使用了sleep将主线程休眠如果我们修改主线程的sleep时间,就会得到不同的结果比如sleep(<100),这样主线程就会在后台线程输出值之前结束,导致没有结果输出

你可能感兴趣的:(java,线程,java编程思想)