• 并发编程入门


    并发编程一直是一个令人困惑的问题,主要的原因在于:使用并发时需要解决的问题会有很多;另外实现并发的方式不止一种,实现方式的选择也是一大问题。

    谈到并发,首先稍微介绍下什么是并发,相信很多人都已经对这个概念比较熟悉,并发编程是相对顺序编程的一种新的模式。它可以一定程度的提高程序的执行速度。主要针对程序的阻塞性,因为程序的阻塞使得程序运行效率降低,而并发在一定程度上解决了程序的阻塞性带来的运行效率问题。所以也可以说,从性能的角度看,如果没有任务会阻塞,那么单处理器上的并发就没有了意义。

    看起来并发也没有多大的作用噢!平常的编程工作并没有遇到很多的阻塞问题,或者涉及到并发问题。就拿Java语言来说。其实不然,Servlet对于熟悉Java的人来说再熟悉不过,而这个作为Web系统最基础的一个类天生就具有多线程性,而对并发的熟悉能使得我们充分利用这些处理器。

    并发编程使得我们可以将程序划分为多个分离的、独立运行的任务,通过多线程机制,这些独立任务中的每一个都将由执行线程来驱动。一个线程就是在进程中的一个单一的顺序控制流,因此,单个进程可以拥有多个并发执行的任务,但程序使得每个任务都好像有其自己的CPU一样。其底层机制是切分CPU时间片,这些通常不需要考虑。[p653]

    了解了并发相关的一些概念,接下来学习学习Java中的并发编程。

    Java中Runnable代表一个任务,要实现线程行为,需要显式地将这个任务附着到线程(Thread)上,

    public class BasicThreads{
    	public static void main (String args[]){
    		Thread t = new Thread(new LiftOff());	//LiftOff是一个任务
    		t.start();
    	}
    }
    

    从任务中产生返回值

    Runnable是执行工作的独立任务,他不返回任何值。如果希望在任务完成时能够返回一个值,那么可以实现Callable接口而不是Runnable接口。
    如何使用Callable呢?
    首先Callable是一种具有类型参数的泛型,它的类型参数表示的是从方法call()中返回的值;并且必须使用ExecutorService.submit()方法调用它,示例:

    public class CallableDemo {
        public static void main(String args[]){
            ExecutorService exec = Executors.newCachedThreadPool();
            ArrayList<Future<String>> results = new ArrayList<Future<String>>();
            for (int i = 0; i < 10; i++) {
                results.add(exec.submit(new TaskwithResult(i)));
            }
            for(Future<String> fs : results){
                try {
                    System.out.println(fs.get());
                }catch(Exception e){
                    System.out.println(e);
                }finally {
                    exec.shutdown();
                }
            }
        }
    }
    
    class TaskwithResult implements Callable<String>{
        private int id ;
        public TaskwithResult(int id){
            this.id = id ;
        }
        public String call(){
            return "result of TaskWithResult " + id ;
        }
    }
    

    submit()方法会产生Future对象,它用Callable返回结果的特定类型进行了参数化,可以用isDone()方法来查询Future是否已经完成。[p659]

    优先级

    线程的优先级,优先级较低的只是执行的频率比较低,并不是优先级低的将不会在优先级高的线程前执行(即,优先级不会导致死锁)。
    在绝大多数时间,线程的优先级都应该以默认优先级运行,试图操作线程优先级通常是一种错误。

    读取线程优先级

    getPriority();
    

    修改优先级

    setPriority();
    

    让步

    yield();
    

    给线程调度机制一个暗示:工作已经差不多了,可以让别的线程使用CPU了。

    但是这个暗示没有任何机制保证它会被采纳。当调用这个方法时,只是在建议具有相同优先级的其他线程可以运行。

  • 相关阅读:
    02点睛Spring4.1-Java Config
    01点睛Spring4.1-依赖注入
    00点睛Spring4.1-环境搭建
    Cas(09)——通过Proxy访问其它Cas应用
    Cas(08)——单点登出
    Cas(07)——建立使用Cas进行单点登录的应用
    Cas(06)——基于数据库的认证
    Cas(05)——修改Cas Server的其它配置
    remove CMakeCache.txt and rerun cmake.On Debian/Ubuntu, package name is libncurses5-dev, on Redhat and derivates it is ncurses-devel.
    解放双手—Cobbler批量自动化部署多版本系统
  • 原文地址:https://www.cnblogs.com/damonzh/p/5745174.html
Copyright © 2020-2023  润新知