zoukankan      html  css  js  c++  java
  • Java并发之需要了解但不能太依赖的东东

    《Java 编程思想》在并发一章中提到了Sleep休眠优先级后台线程,提醒读者需要了解但又不能太依赖他们。就让我们一起看看吧。

    休眠Sleep

    import java.util.concurrent.ExecutorService;
    import java.util.concurrent.Executors;
    import java.util.concurrent.TimeUnit;
    
    public class App {
    	
    	public static void main(String[] args) {
    		ExecutorService exec=Executors.newFixedThreadPool(10);
    		for(int i=0;i<10;i++){
    			exec.execute(new Task());
    		}
    		exec.shutdown();
    	}
    }
    /**
     * 定义任务
     * @author Administrator
     */
    class Task implements Runnable{
    
    	@Override
    	public void run() {
    		try {
    			TimeUnit.SECONDS.sleep(2);
    			System.out.println(Thread.currentThread().getId());
    		} catch (InterruptedException e) {
    			e.printStackTrace();
    		}
    	}
    }

    这里需要注意:

    TimeUnit.SECONDS.sleep(2);

    这是Java5后的新方式,以前你可能这样用:

    Thread.sleep(2*1000);

    不能依赖:不能依赖Sleep来顺序执行任务,如果你需要顺序执行则使用同步机制。


    优先级

    import java.util.concurrent.ExecutorService;
    import java.util.concurrent.Executors;
    import java.util.concurrent.TimeUnit;
    
    public class App {
    
    	public static void main(String[] args) {
    		ExecutorService exec = Executors.newCachedThreadPool();
    		
    		exec.execute(new Task(Thread.MIN_PRIORITY));
    		exec.execute(new Task(Thread.MAX_PRIORITY));
    		exec.shutdown();
    	}
    }
    
    /**
     * 定义任务
     * 
     * @author Administrator
     */
    class Task implements Runnable {
    	private int priority;
    
    	public Task(int priority) {
    		this.priority = priority;
    	}
    
    	@Override
    	public void run() {
    		for (int j = 0; j < 5; j++) {
    			Thread.currentThread().setPriority(priority);
    			for (int i = 0; i < 100; i++) {
    				if (i % 2 == 0) {
    					Thread.yield();
    				}
    			}
    			System.out.println(Thread.currentThread());
    		}
    	}
    }

    线程的优先级将该线程的重要性传递给了调度器,尽管CPU处理现有线程的顺序是不确定的,但调度器倾向于让优先权高的线程先执行,而优先权低的线程执行频率较低。

    不能依赖:所有的程序都应该以默认的优先级运行,试图操纵线程优先级通常是一种错误,因为没法保证。另:尽管JDK有10个优先级,但多数操作系统都不能很好的映射,比如Windows有7个优先级且不固定,映射关系也不确定,Solaris有231个优先级,所以你最好使用可移植的三个级别:MIN_PRIORITY、NORM_PRIORITY和MAX_PRIORITY。


    后台线程

    所谓后台(daemon)线程,是指在程序运行的时候在后台提供一种通用服务的线程,并且这种线程并不属于程序中不可或缺的部分。因此,当所有的非后台线程结束时,程序也就终止了,同时会杀死进程中的所有后台线程。而且后台线程有继承性:后台线程产生的线程都是后台线程。

    import java.util.concurrent.ExecutorService;
    import java.util.concurrent.Executors;
    import java.util.concurrent.ThreadFactory;
    import java.util.concurrent.TimeUnit;
    
    public class App {
    
    	public static void main(String[] args) throws InterruptedException {
    		ExecutorService exec = Executors.newCachedThreadPool(new MyThreadFactory());
    		exec.execute(new Task());
    		exec.shutdown();
    		TimeUnit.MILLISECONDS.sleep(100);
    	}
    }
    
    /**
     * 定义任务
     * 
     * @author Administrator
     */
    class Task implements Runnable {
    
    	@Override
    	public void run() {
    		for(int i=0;i<100;i++){
    			try {
    				TimeUnit.MILLISECONDS.sleep(10);
    			} catch (InterruptedException e) {
    				e.printStackTrace();
    			}
    			System.out.println(i);
    		}
    	}
    }
    
    /**
     * 线程工厂
     * @author Administrator
     *
     */
    class MyThreadFactory implements ThreadFactory{
    
    	@Override
    	public Thread newThread(Runnable r) {
    		Thread t=new Thread(r);
    		t.setDaemon(true);
    		return t;
    	}
    	
    }

    示例中使用“ThreadFactory”来设置线程属性的,可以看到输出是打印不完100个就结束了,如果你把Deamon设置为false,就能打印全部。

    不能依赖:所有非后台线程一旦结束,后台线程就会立刻终止,这不能以一种优雅的方式关闭线程,所以可能会得到意想不到的结果。

    PS:以上三种不能说完全摒弃不用,既然设计了就可能有用的,只是要注意使用弊端,从而达到合理使用。


    出处:http://www.zhaiqianfeng.com    
    本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
  • 相关阅读:
    重载运算符
    旅行家的预算(贪心)
    树屋阶梯(卡特兰数+高精除低精+高精乘低精)
    种树 3(差分约束)
    差分约束系统详解
    最优分解方案(贪心+高精乘单精)
    雷达安装(贪心)
    加工生产调度(Johnson算法 双机流水作业调度问题)

    Jquery整理
  • 原文地址:https://www.cnblogs.com/zhaiqianfeng/p/4620133.html
Copyright © 2011-2022 走看看