精华内容
下载资源
问答
  • Java项目开发实例代码

    2013-04-10 09:59:17
    Java项目开发实例自学手册上的内容配套的代码
  • java代码实例项目

    2008-12-08 20:13:45
    基于java基础的编程实例实现银行项目的编程实例仅供参考,里面有详尽的代码
  • java 接口 代码实例

    2011-04-02 10:43:12
    java 接口 代码实例java 接口 代码实例java 接口 代码实例java 接口 代码实例
  • 今天编就为大家分享一篇关于java模拟ajax访问另一个项目的controller代码实例编觉得内容挺不错的,现在分享给大家,具有很好的参考价值,需要的朋友一起跟随编来看看吧
  • java 项目实例开发代码 绝对经典 java 项目实例开发代码 绝对经典 java 项目实例开发代码 绝对经典
  • java事件单击事件 实例代码java事件单击事件 实例代码java事件单击事件 实例代码
  • java实现http请求,java解析json与java对象转换,项目代码实例.直接下载源代码可以运行。
  • MongoDB Java操作大全 源代码 实例

    热门讨论 2012-03-18 18:09:41
    MongoDB Java操作大全 源代码 实例
  • JAVA+Solr分词项目工程实例代码学习
  • 2018年达内最新java培训资料+项目代码实例,含java基础、面向对象、SE、前端基础、数据库、框架知识
  • java后端小实例

    2018-07-23 15:28:02
    java后端小实例java后端小实例java后端小实例java后端小实例
  • 论坛短消息java代码实例 内附论坛代码实例、数据库、ppt说明文档
  • JAVA小项目实例源码—学习娱乐小助手

    万次阅读 多人点赞 2018-03-03 09:50:32
    项目目录: MyJFrame:实现项目界面样式; AppProcess:实现调用api或爬虫拿数据; NLIProcess:解析用户输入语句意图; lib中是程序开发需要用到的jar包列表。主要代码说明: 程序不同功能领域由选项卡...

    代码地址如下:
    http://www.demodashi.com/demo/11456.html

    一、程序实现

    • 项目目录:
      MyJFrame:实现项目界面样式;
      AppProcess:实现调用api或爬虫拿数据;
      NLIProcess:解析用户输入语句意图;
      lib中是程序开发需要用到的jar包列表。

    • 主要代码说明:

    程序不同功能领域由选项卡JTabbedPane展示。用户输入哪个功能领域的问题,将由该领域的选项卡展示答案。

    在选项卡中添加选项:

                tabbedPanel.addTab("笑话",panel_joke);  
                tabbedPanel.addTab("新闻",panel_news);   
                tabbedPanel.addTab("星座",panel_hor);  
                tabbedPanel.addTab("成语",panel_idiom);  
                tabbedPanel.addTab("解梦",panel_oneir);  

    切换选项卡时给出对应功能领域的语料示例:

    tabbedPanel.addChangeListener(new ChangeListener(){  
    
                @Override
                public void stateChanged(ChangeEvent arg0) {
                    // TODO Auto-generated method stub
                    int index = tabbedPanel.getSelectedIndex();
                    areaTxt.setText(introduce + introduces[index]);
                    ((JScrollPane)tabbedPanel.getComponent(index)).setViewportView(areaTxt);
                }  
            });  
    

    输出答案时切换为对应功能选项卡展示答案:

    private void jButton_sendActionPerformed(java.awt.event.ActionEvent evt) {
            // TODO add your handling code here:
            Map<String, Object> retMap = app.process(jTextField1.getText());
            jLabel2.setText("");
            if (retMap.containsKey("ds")) {
                jLabel2.setText(retMap.get("ds").toString());
                jLabel2.setForeground(Color.red);
            } else if (retMap.containsKey("joke")) {
                Object obj = retMap.get("joke");
                tabbedPanel.setSelectedIndex(0);
                JScrollPane jpanel = ((JScrollPane) tabbedPanel.getComponent(0));
                if (obj instanceof String) {
                    areaTxt.setText(obj.toString());
                    jpanel.setViewportView(areaTxt);
                } else {
                    JLabel jLabel = new JLabel();
                    if (obj != null) {
                        ImageIcon image = new ImageIcon((URL) obj);
                        jLabel.setIcon(image);
                    } else {
                        jLabel.setText("图片加载失败!");
                    }
                    jpanel.setViewportView(jLabel);
    
                }
            }else if (retMap.containsKey("horoname")){
                Object obj = retMap.get("horoname");
                tabbedPanel.setSelectedIndex(2);
                JScrollPane jpanel = ((JScrollPane) tabbedPanel.getComponent(2));
                areaTxt.setText(obj.toString());
                jpanel.setViewportView(areaTxt);
            }else if(retMap.containsKey("news")){
                Object obj = retMap.get("news");
                tabbedPanel.setSelectedIndex(1);
                JScrollPane jpanel = ((JScrollPane) tabbedPanel.getComponent(1));
    
                if (obj instanceof String) {
                    areaTxt.setText(obj.toString());
                    jpanel.setViewportView(areaTxt);
                }else{
                    @SuppressWarnings("unchecked")
                    Map<String, List<String>> newsMap = (HashMap<String, List<String>>)obj;
                    List<String> titleList = newsMap.get("title");
                    final List<String> urlList = newsMap.get("url");
    
                    table = getSimpleTable(titleList);
                    jpanel.setViewportView(table);
                    table.addMouseListener(new MouseListener(){
    
                        @Override
                        public void mouseClicked(MouseEvent arg0) {
                            // TODO Auto-generated method stub
                            // 取得用户所选行的行数
                            int selectRows=table.getSelectedRows().length;
                            if(selectRows==1){
                              // 取得用户所选单行 
                              int selectedRowIndex = table.getSelectedRow(); 
                              String url = urlList.get(selectedRowIndex);
                              Desktop desktop = Desktop.getDesktop();
                                try {
                                    desktop.browse(new URI(url));
                                } catch (IOException | URISyntaxException e1) {
                                    e1.printStackTrace();
                                }
                            }                       
    
                        }
    
                        @Override
                        public void mouseEntered(MouseEvent arg0) {}
    
                        @Override
                        public void mouseExited(MouseEvent arg0) {}
    
                        @Override
                        public void mousePressed(MouseEvent arg0) {}
    
                        @Override
                        public void mouseReleased(MouseEvent arg0) {}});
    
    
                }           
    
            }else if(retMap.containsKey("oneiromancy")){
                Object obj = retMap.get("oneiromancy");
                tabbedPanel.setSelectedIndex(4);
                final JScrollPane jpanel = ((JScrollPane) tabbedPanel.getComponent(4));
    
                if (obj instanceof String) {
                    areaTxt.setText(obj.toString());
                    jpanel.setViewportView(areaTxt);
                }else{
                    @SuppressWarnings("unchecked")
                    Map<String, List<String>> OneirMap = (HashMap<String, List<String>>)obj;
                    List<String> wordList = OneirMap.get("word");
                    final List<String> urlList = OneirMap.get("url");
                    table = getSimpleTable(wordList);
                    jpanel.setViewportView(table);
                    table.addMouseListener(new MouseListener(){
    
                        @Override
                        public void mouseClicked(MouseEvent arg0) {
                            // TODO Auto-generated method stub
                            // 取得用户所选行的行数
                            int selectRows=table.getSelectedRows().length;
                            if(selectRows==1){
                              // 取得用户所选单行 
                              int selectedRowIndex = table.getSelectedRow(); 
                              String url = urlList.get(selectedRowIndex);
                              String answer = app.getOneirData(url);
                              areaTxt.setText(answer);
                              jpanel.setViewportView(areaTxt);
                            }                       
    
                        }
    
                        @Override
                        public void mouseEntered(MouseEvent arg0) {}
    
                        @Override
                        public void mouseExited(MouseEvent arg0) {}
    
                        @Override
                        public void mousePressed(MouseEvent arg0) {}
    
                        @Override
                        public void mouseReleased(MouseEvent arg0) {}});
    
                }
    
            }else if(retMap.containsKey("idioms")){
            Object obj = retMap.get("idioms");
            tabbedPanel.setSelectedIndex(3);
            final JScrollPane jpanel = ((JScrollPane) tabbedPanel.getComponent(3));
    
            if (obj instanceof String) {
                areaTxt.setText(obj.toString());
                jpanel.setViewportView(areaTxt);
            }else{
                @SuppressWarnings("unchecked")
                Map<String, List<String>> OneirMap = (HashMap<String, List<String>>)obj;
                List<String> nameList = OneirMap.get("name");
                final List<String> idList = OneirMap.get("id");
                table = getSimpleTable(nameList);
                jpanel.setViewportView(table);
                table.addMouseListener(new MouseListener(){
    
                    @Override
                    public void mouseClicked(MouseEvent arg0) {
                        // TODO Auto-generated method stub
                        // 取得用户所选行的行数
                        int selectRows=table.getSelectedRows().length;
                        if(selectRows==1){
                          // 取得用户所选单行 
                          int selectedRowIndex = table.getSelectedRow(); 
                          String id = idList.get(selectedRowIndex);
                          String answer = app.getIdiomsP(id);
                          areaTxt.setText(answer);
                          jpanel.setViewportView(areaTxt);
                        }                       
    
                    }
    
                    @Override
                    public void mouseEntered(MouseEvent arg0) {}
    
                    @Override
                    public void mouseExited(MouseEvent arg0) {}
    
                    @Override
                    public void mousePressed(MouseEvent arg0) {}
    
                    @Override
                    public void mouseReleased(MouseEvent arg0) {}});
    
            }
    
        }
    
        }
    

    使用Jsoup解析XML:

    private Map<String, List<String>> getNewsMap(String type){
            Map<String, List<String>> newsMap = new HashMap<>();
            List<String> titleList = new ArrayList<>();
            List<String> urlList = new ArrayList<>();
            String url = MessageFormat.format("http://www.chinanews.com/rss/{0}.xml", type);
            String httpContent = getHttpContent(url,"gbk");
    
            Document doc = Jsoup.parse(httpContent, "", new Parser(new XmlTreeBuilder()));
            //item
            Elements itemElements = doc.select("item");
            if(itemElements != null){                   
                for(Element e : itemElements){
                    String title = e.select("title").first().text();
                    String link = e.select("link").first().text();
                    titleList.add(title);
                    urlList.add(link);
                }
    
                newsMap.put("title", titleList);
                newsMap.put("url", urlList);
            }
    
            return newsMap;
        }

    二、运行效果

    • 运行截图如下:
      笑话(支持看笑话、看趣图):

      新闻(显示新闻列表,点选后可进入新闻详情页):

      星座(支持查今日、明日、本周、本月、今年运势):

      成语(支持成语释义、查带某字、词的成语):

      解梦:

    三、其他补充

    • 新闻:
      点选新闻标题后会调用浏览器显示新闻详细页(这里本来打算用JEditorPane实现的,实现后发现新闻网页格式变形,查询资料知道JEditorPane 存在缺陷: 不支持CSS样式和JavaScript。所以改为了调用浏览器打开新闻页。)
    • 星座:
      没有找到免费的api接口,星座数据是用爬虫爬下来的,所以第一次问星座问题时出结果会有点慢。
      JAVA小项目实例源码—学习娱乐小助手

    代码地址如下:
    http://www.demodashi.com/demo/11456.html

    注:本文著作权归作者,由demo大师发表,拒绝转载,转载需要作者授权

    展开全文
  • 包含Java项目开发实例自学手册源代码,适合初学者自学
  • java 150个小实例源码

    千次下载 热门讨论 2015-09-02 11:18:32
    提供java 150个经典小实例的源代码,对初学者想要练习学习java非常有帮助。
  • Java非对称加密源码实例 1个目标文件 摘要:Java源码,算法相关,非对称加密 Java非对称加密源程序代码实例,本例中使用RSA加密技术,定义加密算法可用 DES,DESede,Blowfish等。 设定字符串为“张三,你好,我是李四”...
  • JAVA版SSH框架实例代码及分页实例,简单实例来精通struts,Hibernate,Spring,连接Mysql数据库
  • java《六》获取项目路径实例代码

    万次阅读 2018-08-10 11:59:04
    实例代码: package com.util; import com.xxg.main.Main; /** * java获取项目系统路径 * @author yushen * */ public class pathUitl { //java获取项目系统路径 public static void main(String[] args) ...

    示例图片:

    实例代码:

    package com.util;
    
    import com.xxg.main.Main;
    
    /**
     * java获取项目系统路径
     * @author yushen
     *
     */
    public class pathUitl {
    	//java获取项目系统路径
    	public static void main(String[] args) {
    		String u1 = System.getProperty("user.dir");
    		System.out.println(u1);
    		
    		String u2 = Thread.currentThread().getContextClassLoader().getResource("").getPath(); 
    		System.out.println(u2);
    		
    		String u3 = Thread.currentThread().getContextClassLoader().getResource(".").getPath();
    		System.out.println(u3);
    		
    		String u4 = System.getProperty("java.class.path"); 
    		System.out.println(u4);
    		
    		String u5 = pathUitl.class.getResource("/").toString().substring(6);
    		System.out.println(u5);
    		 
    	}
    }
    

     

    展开全文
  • java调用webservice实例代码,分为俩个web小项目,一个为Client、一个为webservice
  • Java 线程池详解及实例代码

    千次阅读 2018-06-08 07:46:07
    转载自 Java 线程池详解及实例代码这篇文章主要介绍了Java 线程池的相关资料,并符实例代码,帮助大家学习参考,需要的朋友可以参考下线程池的技术背景在面向对象编程中,创建和销毁对象是很费时间的,因为创建一个...

    转载自  Java 线程池详解及实例代码

    这篇文章主要介绍了Java 线程池的相关资料,并符实例代码,帮助大家学习参考,需要的朋友可以参考下

    线程池的技术背景

    在面向对象编程中,创建和销毁对象是很费时间的,因为创建一个对象要获取内存资源或者其它更多资源。在Java中更是如此,虚拟机将试图跟踪每一个对象,以便能够在对象销毁后进行垃圾回收。

    所以提高服务程序效率的一个手段就是尽可能减少创建和销毁对象的次数,特别是一些很耗资源的对象创建和销毁。如何利用已有对象来服务就是一个需要解决的关键问题,其实这就是一些”池化资源”技术产生的原因。

    例如Android中常见到的很多通用组件一般都离不开”池”的概念,如各种图片加载库,网络请求库,即使Android的消息传递机制中的Meaasge当使用Meaasge.obtain()就是使用的Meaasge池中的对象,因此这个概念很重要。本文将介绍的线程池技术同样符合这一思想。

    线程池的优点:

    1.重用线程池中的线程,减少因对象创建,销毁所带来的性能开销;

    2.能有效的控制线程的最大并发数,提高系统资源利用率,同时避免过多的资源竞争,避免堵塞;

    3.能够多线程进行简单的管理,使线程的使用简单、高效。

    线程池框架Executor

    java中的线程池是通过Executor框架实现的,Executor 框架包括类:Executor,Executors,ExecutorService,ThreadPoolExecutor ,Callable和Future、FutureTask的使用等。

    Executor: 所有线程池的接口,只有一个方法。

    public interface Executor {  
     void execute(Runnable command);  
    }

    ExecutorService: 增加Executor的行为,是Executor实现类的最直接接口。

    Executors: 提供了一系列工厂方法用于创先线程池,返回的线程池都实现了ExecutorService 接口。

    ThreadPoolExecutor:线程池的具体实现类,一般用的各种线程池都是基于这个类实现的。 构造方法如下:

    public ThreadPoolExecutor(int corePoolSize,
            int maximumPoolSize,
            long keepAliveTime,
            TimeUnit unit,
            BlockingQueue<Runnable> workQueue) {
        this(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue,
    
        Executors.defaultThreadFactory(), defaultHandler);
    
    }

    corePoolSize:线程池的核心线程数,线程池中运行的线程数也永远不会超过 corePoolSize 个,默认情况下可以一直存活。可以通过设置allowCoreThreadTimeOut为True,此时 核心线程数就是0,此时keepAliveTime控制所有线程的超时时间。

    maximumPoolSize:线程池允许的最大线程数;

    keepAliveTime: 指的是空闲线程结束的超时时间;

    unit :是一个枚举,表示 keepAliveTime 的单位;

    workQueue:表示存放任务的BlockingQueue<Runnable队列。

    BlockingQueue:阻塞队列(BlockingQueue)是java.util.concurrent下的主要用来控制线程同步的工具。如果BlockQueue是空的,从BlockingQueue取东西的操作将会被阻断进入等待状态,直到BlockingQueue进了东西才会被唤醒。同样,如果BlockingQueue是满的,任何试图往里存东西的操作也会被阻断进入等待状态,直到BlockingQueue里有空间才会被唤醒继续操作。 阻塞队列常用于生产者和消费者的场景,生产者是往队列里添加元素的线程,消费者是从队列里拿元素的线程。阻塞队列就是生产者存放元素的容器,而消费者也只从容器里拿元素。具体的实现类有LinkedBlockingQueue,ArrayBlockingQueued等。一般其内部的都是通过Lock和Condition(显示锁(Lock)及Condition的学习与使用)来实现阻塞和唤醒。

    线程池的工作过程如下:

    线程池刚创建时,里面没有一个线程。任务队列是作为参数传进来的。不过,就算队列里面有任务,线程池也不会马上执行它们。

    当调用 execute() 方法添加一个任务时,线程池会做如下判断:

    如果正在运行的线程数量小于 corePoolSize,那么马上创建线程运行这个任务;

    如果正在运行的线程数量大于或等于 corePoolSize,那么将这个任务放入队列;

    如果这时候队列满了,而且正在运行的线程数量小于 maximumPoolSize,那么还是要创建非核心线程立刻运行这个任务;

    如果队列满了,而且正在运行的线程数量大于或等于 maximumPoolSize,那么线程池会抛出异常RejectExecutionException。

    当一个线程完成任务时,它会从队列中取下一个任务来执行。

    当一个线程无事可做,超过一定的时间(keepAliveTime)时,线程池会判断,如果当前运行的线程数大于 corePoolSize,那么这个线程就被停掉。所以线程池的所有任务完成后,它最终会收缩到 corePoolSize 的大小。

    线程池的创建和使用

    生成线程池采用了工具类Executors的静态方法,以下是几种常见的线程池。

    SingleThreadExecutor:单个后台线程 (其缓冲队列是无界的)

    public static ExecutorService newSingleThreadExecutor() {  
     return new FinalizableDelegatedExecutorService (
      new ThreadPoolExecutor(1, 1,         
      0L, TimeUnit.MILLISECONDS,         
      new LinkedBlockingQueue<Runnable>())); 
    }

    创建一个单线程的线程池。这个线程池只有一个核心线程在工作,也就是相当于单线程串行执行所有任务。如果这个唯一的线程因为异常结束,那么会有一个新的线程来替代它。此线程池保证所有任务的执行顺序按照任务的提交顺序执行。

    FixedThreadPool:只有核心线程的线程池,大小固定 (其缓冲队列是无界的) 。

    public static ExecutorService newFixedThreadPool(int nThreads) {         
            return new ThreadPoolExecutor(nThreads, nThreads,                                       
                0L, TimeUnit.MILLISECONDS,                                         
                new LinkedBlockingQueue<Runnable>());     
    }

    创建固定大小的线程池。每次提交一个任务就创建一个线程,直到线程达到线程池的最大大小。线程池的大小一旦达到最大值就会保持不变,如果某个线程因为执行异常而结束,那么线程池会补充一个新线程。

    CachedThreadPool:无界线程池,可以进行自动线程回收。

    public static ExecutorService newCachedThreadPool() {   
     return new ThreadPoolExecutor(0,Integer.MAX_VALUE,           
       60L, TimeUnit.SECONDS,          
       new SynchronousQueue<Runnable>());  
    }

    如果线程池的大小超过了处理任务所需要的线程,那么就会回收部分空闲(60秒不执行任务)的线程,当任务数增加时,此线程池又可以智能的添加新线程来处理任务。此线程池不会对线程池大小做限制,线程池大小完全依赖于操作系统(或者说JVM)能够创建的最大线程大小。SynchronousQueue是一个是缓冲区为1的阻塞队列。

    ScheduledThreadPool:核心线程池固定,大小无限的线程池。此线程池支持定时以及周期性执行任务的需求。

    public static ExecutorService newScheduledThreadPool(int corePoolSize) {   
     return new ScheduledThreadPool(corePoolSize, 
        Integer.MAX_VALUE,             
        DEFAULT_KEEPALIVE_MILLIS, MILLISECONDS,             
        new DelayedWorkQueue()); 
    }

    创建一个周期性执行任务的线程池。如果闲置,非核心线程池会在DEFAULT_KEEPALIVEMILLIS时间内回收。

    线程池最常用的提交任务的方法有两种:

    execute:

    ExecutorService.execute(Runnable runable);

    submit:

    FutureTask task = ExecutorService.submit(Runnable runnable);
    FutureTask<T> task = ExecutorService.submit(Runnable runnable,T Result);

    FutureTask<T> task = ExecutorService.submit(Callable<T> callable);

    submit(Callable callable)的实现,submit(Runnable runnable)同理。

    public <T> Future<T> submit(Callable<T> task) {
     if (task == null) throw new NullPointerException();
     FutureTask<T> ftask = newTaskFor(task);
     execute(ftask);
     return ftask;
    }

    可以看出submit开启的是有返回结果的任务,会返回一个FutureTask对象,这样就能通过get()方法得到结果。submit最终调用的也是execute(Runnable runable),submit只是将Callable对象或Runnable封装成一个FutureTask对象,因为FutureTask是个Runnable,所以可以在execute中执行。关于Callable对象和Runnable怎么封装成FutureTask对象,见Callable和Future、FutureTask的使用。

    线程池实现的原理

    如果只讲线程池的使用,那这篇博客没有什么大的价值,充其量也就是熟悉Executor相关API的过程。线程池的实现过程没有用到Synchronized关键字,用的都是Volatile,Lock和同步(阻塞)队列,Atomic相关类,FutureTask等等,因为后者的性能更优。理解的过程可以很好的学习源码中并发控制的思想。

    在开篇提到过线程池的优点是可总结为以下三点:

    线程复用

    控制最大并发数

    管理线程

    1.线程复用过程

    理解线程复用原理首先应了解线程生命周期。

    在线程的生命周期中,它要经过新建(New)、就绪(Runnable)、运行(Running)、阻塞(Blocked)和死亡(Dead)5种状态。

    Thread通过new来新建一个线程,这个过程是是初始化一些线程信息,如线程名,id,线程所属group等,可以认为只是个普通的对象。调用Thread的start()后Java虚拟机会为其创建方法调用栈和程序计数器,同时将hasBeenStarted为true,之后调用start方法就会有异常。

    处于这个状态中的线程并没有开始运行,只是表示该线程可以运行了。至于该线程何时开始运行,取决于JVM里线程调度器的调度。当线程获取cpu后,run()方法会被调用。不要自己去调用Thread的run()方法。之后根据CPU的调度在就绪——运行——阻塞间切换,直到run()方法结束或其他方式停止线程,进入dead状态。

    所以实现线程复用的原理应该就是要保持线程处于存活状态(就绪,运行或阻塞)。接下来来看下ThreadPoolExecutor是怎么实现线程复用的。

    在ThreadPoolExecutor主要Worker类来控制线程的复用。看下Worker类简化后的代码,这样方便理解:

    private final class Worker implements Runnable {
    final Thread thread;
    
    Runnable firstTask;
    
    Worker(Runnable firstTask) {
    
    this.firstTask = firstTask;
    
    this.thread = getThreadFactory().newThread(this);
    
    }
    
    public void run() {
    
    runWorker(this);
    
    }
    
    final void runWorker(Worker w) {
    
    Runnable task = w.firstTask;
    
    w.firstTask = null;
    
    while (task != null || (task = getTask()) != null){
    
    task.run();
    
    }
    
    }

    Worker是一个Runnable,同时拥有一个thread,这个thread就是要开启的线程,在新建Worker对象时同时新建一个Thread对象,同时将Worker自己作为参数传入TThread,这样当Thread的start()方法调用时,运行的实际上是Worker的run()方法,接着到runWorker()中,有个while循环,一直从getTask()里得到Runnable对象,顺序执行。getTask()又是怎么得到Runnable对象的呢?

    依旧是简化后的代码:

    private Runnable getTask() {
     if(一些特殊情况) {
      return null;
     }
    Runnable r = workQueue.take();
    
    return r;
    
    }

    这个workQueue就是初始化ThreadPoolExecutor时存放任务的BlockingQueue队列,这个队列里的存放的都是将要执行的Runnable任务。因为BlockingQueue是个阻塞队列,BlockingQueue.take()得到如果是空,则进入等待状态直到BlockingQueue有新的对象被加入时唤醒阻塞的线程。所以一般情况Thread的run()方法就不会结束,而是不断执行从workQueue里的Runnable任务,这就达到了线程复用的原理了。

    2.控制最大并发数

    那Runnable是什么时候放入workQueue?Worker又是什么时候创建,Worker里的Thread的又是什么时候调用start()开启新线程来执行Worker的run()方法的呢?有上面的分析看出Worker里的runWorker()执行任务时是一个接一个,串行进行的,那并发是怎么体现的呢?

    很容易想到是在execute(Runnable runnable)时会做上面的一些任务。看下execute里是怎么做的。

    execute:

    简化后的代码

    public void execute(Runnable command) {
     if (command == null)
      throw new NullPointerException();
    int c = ctl.get();
    
    // 当前线程数 < corePoolSize
    
    if (workerCountOf(c) < corePoolSize) {
    
    // 直接启动新的线程。
    
    if (addWorker(command, true))
    
    return;
    
    c = ctl.get();
    
    }
    
    // 活动线程数 >= corePoolSize
    
    // runState为RUNNING && 队列未满
    
    if (isRunning(c) && workQueue.offer(command)) {
    
    int recheck = ctl.get();
    
    // 再次检验是否为RUNNING状态
    
    // 非RUNNING状态 则从workQueue中移除任务并拒绝
    
    if (!isRunning(recheck) && remove(command))
    
    reject(command);// 采用线程池指定的策略拒绝任务
    
    // 两种情况:
    
    // 1.非RUNNING状态拒绝新的任务
    
    // 2.队列满了启动新的线程失败(workCount > maximumPoolSize)
    
    } else if (!addWorker(command, false))
    
    reject(command);
    
    }

    addWorker:

    简化后的代码

    private boolean addWorker(Runnable firstTask, boolean core) {
    int wc = workerCountOf(c);
    
    if (wc >= (core ? corePoolSize : maximumPoolSize)) {
    
    return false;
    
    }
    
    w = new Worker(firstTask);
    
    final Thread t = w.thread;
    
    t.start();
    
    }

    根据代码再来看上面提到的线程池工作过程中的添加任务的情况:

    * 如果正在运行的线程数量小于 corePoolSize,那么马上创建线程运行这个任务;   
    * 如果正在运行的线程数量大于或等于 corePoolSize,那么将这个任务放入队列;
    * 如果这时候队列满了,而且正在运行的线程数量小于 maximumPoolSize,那么还是要创建非核心线程立刻运行这个任务;
    * 如果队列满了,而且正在运行的线程数量大于或等于 maximumPoolSize,那么线程池会抛出异常RejectExecutionException。

    这就是Android的AsyncTask在并行执行是在超出最大任务数是抛出RejectExecutionException的原因所在,详见基于最新版本的AsyncTask源码解读及AsyncTask的黑暗面

    通过addWorker如果成功创建新的线程成功,则通过start()开启新线程,同时将firstTask作为这个Worker里的run()中执行的第一个任务。

    虽然每个Worker的任务是串行处理,但如果创建了多个Worker,因为共用一个workQueue,所以就会并行处理了。

    所以根据corePoolSize和maximumPoolSize来控制最大并发数。大致过程可用下图表示。

    上面的讲解和图来可以很好的理解的这个过程。

    如果是做Android开发的,并且对Handler原理比较熟悉,你可能会觉得这个图挺熟悉,其中的一些过程和Handler,Looper,Meaasge使用中,很相似。Handler.send(Message)相当于execute(Runnuble),Looper中维护的Meaasge队列相当于BlockingQueue,只不过需要自己通过同步来维护这个队列,Looper中的loop()函数循环从Meaasge队列取Meaasge和Worker中的runWork()不断从BlockingQueue取Runnable是同样的道理。

    3.管理线程

    通过线程池可以很好的管理线程的复用,控制并发数,以及销毁等过程,线程的复用和控制并发上面已经讲了,而线程的管理过程已经穿插在其中了,也很好理解。

    在ThreadPoolExecutor有个ctl的AtomicInteger变量。通过这一个变量保存了两个内容:

    所有线程的数量 每个线程所处的状态 其中低29位存线程数,高3位存runState,通过位运算来得到不同的值。

    private final AtomicInteger ctl = new AtomicInteger(ctlOf(RUNNING, 0));
    //得到线程的状态
    
    private static int runStateOf(int c) {
    
    return c & ~CAPACITY;
    
    }
    
    //得到Worker的的数量
    
    private static int workerCountOf(int c) {
    
    return c & CAPACITY;
    
    }
    
    // 判断线程是否在运行
    
    private static boolean isRunning(int c) {
    
    return c < SHUTDOWN;
    
    }

    这里主要通过shutdown和shutdownNow()来分析线程池的关闭过程。首先线程池有五种状态来控制任务添加与执行。主要介绍以下三种:

    RUNNING状态:线程池正常运行,可以接受新的任务并处理队列中的任务;

    SHUTDOWN状态:不再接受新的任务,但是会执行队列中的任务;

    STOP状态:不再接受新任务,不处理队列中的任务 shutdown这个方法会将runState置为SHUTDOWN,会终止所有空闲的线程,而仍在工作的线程不受影响,所以队列中的任务人会被执行。

    shutdownNow方法将runState置为STOP。和shutdown方法的区别,这个方法会终止所有的线程,所以队列中的任务也不会被执行了。

    总结
    通过对ThreadPoolExecutor源码的分析,从总体上了解了线程池的创建,任务的添加,执行等过程,熟悉这些过程,使用线程池就会更轻松了。

    而从中学到的一些对并发控制,以及生产者——消费者模型任务处理的使用,对以后理解或解决其他相关问题会有很大的帮助。比如Android中的Handler机制,而Looper中的Messager队列用一个BlookQueue来处理同样是可以的,这写就是读源码的收获吧。


    展开全文
  • java+web项目开发,javaweb开发完整实例代码

    千次下载 热门讨论 2014-03-20 11:18:14
    深入体验java+web开发,javaweb开发完整实例代码,里面包含使用说明和注解,共有十个不同类型的项目案例供你学习。
  • Kafka java实例代码

    万次阅读 2017-08-14 15:15:30
    工程准备1、首先搭建Kafka集群环境,这里我们kafka的集群环境已经搭建好的,详情参考:http://blog.csdn.net/liulihui1988/article/details/770990222...kafka Maven项目 pom.xml 文件,执行添加一下依赖代码 <!-- Ka

    工程准备

    1、首先搭建Kafka集群环境,这里我们kafka的集群环境已经搭建好的,详情参考:

    http://blog.csdn.net/liulihui1988/article/details/77099022

    2、搭建Maven工程,普通工程需要导入相关的依赖包,想必Maven工程相对简单,如下图:

    这里写图片描述

    • kafka Maven项目 pom.xml 文件,执行添加一下依赖代码
            <!-- Kafka  依赖包-->
            <dependency>
                <groupId>org.apache.kafka</groupId>
                <artifactId>kafka_2.10</artifactId>
                <version>0.8.2.0</version>
            </dependency>

    Kafka java实例代码

    • 消息生产者代码示例
    package com.jxl.cloub.kafka;
    
    import java.util.Date;
    import java.util.Properties;
    import kafka.javaapi.producer.Producer;
    import kafka.producer.KeyedMessage;
    import kafka.producer.ProducerConfig;
    
    /**
     * 消息生产者代码示例
     *
     */
    public class ProducerDemo {
    
        public static void main(String[] args) {
            int events=100;
            // 设置配置属性
            Properties props = new Properties();
            props.put("metadata.broker.list","centos-node6:19092,centos-node7:19092,centos-node8:19092");
            props.put("serializer.class", "kafka.serializer.StringEncoder");
            // key.serializer.class默认为serializer.class
            props.put("key.serializer.class", "kafka.serializer.StringEncoder");
            // 可选配置,如果不配置,则使用默认的partitioner
            props.put("partitioner.class", "com.jxl.cloub.kafka.PartitionerDemo");
            // 触发acknowledgement机制,否则是fire and forget,可能会引起数据丢失
            // 值为0,1,-1,可以参考
            props.put("request.required.acks", "1");
            ProducerConfig config = new ProducerConfig(props);
    
            // 创建producer
            Producer<String, String> producer = new Producer<String, String>(config);
            // 产生并发送消息
            long start=System.currentTimeMillis();
            for (long i = 0; i < events; i++) {
                long runtime = new Date().getTime();
                String ip = "10.1.6." + i;//rnd.nextInt(255);
                String msg = runtime + ",www.example.com," + ip;
                //如果topic不存在,则会自动创建,默认replication-factor为1,partitions为0
                KeyedMessage<String, String> data = new KeyedMessage<String, String>(
                        "test", ip, msg);
                producer.send(data);
            }
            System.out.println("耗时:" + (System.currentTimeMillis() - start));
            // 关闭producer
            producer.close();
        }
    
    }
    • 消息消费者代码示例
    package com.jxl.cloub.kafka;
    
    import java.util.HashMap;
    import java.util.List;
    import java.util.Map;
    import java.util.Properties;
    import java.util.concurrent.ExecutorService;
    import java.util.concurrent.Executors;
    
    import kafka.consumer.Consumer;
    import kafka.consumer.ConsumerConfig;
    import kafka.consumer.KafkaStream;
    import kafka.javaapi.consumer.ConsumerConnector;
    
    /**
     * 消息消费者代码示例
     *
     */
    public class ConsumerDemo {
    
        private final ConsumerConnector consumer;
        private final String topic;
        private ExecutorService executor;
    
        public ConsumerDemo(String a_zookeeper, String a_groupId, String a_topic) {
            consumer = Consumer.createJavaConsumerConnector(createConsumerConfig(a_zookeeper,a_groupId));
            this.topic = a_topic;
        }
    
        public void shutdown() {
            if (consumer != null)
                consumer.shutdown();
            if (executor != null)
                executor.shutdown();
        }
    
        public void run(int numThreads) {
            Map<String, Integer> topicCountMap = new HashMap<String, Integer>();
            topicCountMap.put(topic, new Integer(numThreads));
            Map<String, List<KafkaStream<byte[], byte[]>>> consumerMap = consumer
                    .createMessageStreams(topicCountMap);
            List<KafkaStream<byte[], byte[]>> streams = consumerMap.get(topic);
    
            // now launch all the threads
            executor = Executors.newFixedThreadPool(numThreads);
    
            // now create an object to consume the messages
            //
            int threadNumber = 0;
            for (final KafkaStream stream : streams) {
                executor.submit(new ConsumerMsgTask(stream, threadNumber));
                threadNumber++;
            }
        }
    
        private static ConsumerConfig createConsumerConfig(String a_zookeeper,
                String a_groupId) {
            Properties props = new Properties();
            props.put("zookeeper.connect", a_zookeeper);
            props.put("group.id", a_groupId);
            props.put("zookeeper.session.timeout.ms", "400");
            props.put("zookeeper.sync.time.ms", "200");
            props.put("auto.commit.interval.ms", "1000");
    
            return new ConsumerConfig(props);
        }
    
        public static void main(String[] arg) {
            String[] args = { "centos-node7:2181", "0", "test", "12" };
            String zooKeeper = args[0];
            String groupId = args[1];
            String topic = args[2];
            int threads = Integer.parseInt(args[3]);
    
            ConsumerDemo demo = new ConsumerDemo(zooKeeper, groupId, topic);
            demo.run(threads);
    
            try {
                Thread.sleep(10000);
            } catch (InterruptedException ie) {
    
            }
            demo.shutdown();
        }
    
    }
    
    • 分区Partitioner类示例
    package com.jxl.cloub.kafka;
    
    import kafka.producer.Partitioner;
    import kafka.utils.VerifiableProperties;
    
    /**
     * Partitioner类示例
     *
     */
    public class PartitionerDemo implements Partitioner{
    
        public PartitionerDemo(VerifiableProperties props) {}
    
        public int partition(Object obj, int numPartitions) {
            int partition = 0;
            if (obj instanceof String) {
                String key=(String)obj;
                int offset = key.lastIndexOf('.');
                if (offset > 0) {
                    partition = Integer.parseInt(key.substring(offset + 1)) % numPartitions;
                }
            }else{
                partition = obj.toString().length() % numPartitions;
            }
    
            return partition;
        }
    
    }
    
    • 消息处理类
    package com.jxl.cloub.kafka;
    
    import kafka.consumer.ConsumerIterator;
    import kafka.consumer.KafkaStream;
    
    /**
     * 
     *消息处理类
     */
    public class ConsumerMsgTask implements Runnable {
    
        private KafkaStream m_stream;
        private int m_threadNumber;
    
        public ConsumerMsgTask(KafkaStream stream, int threadNumber) {
            m_threadNumber = threadNumber;
            m_stream = stream;
        }
    
        public void run() {
            ConsumerIterator<byte[], byte[]> it = m_stream.iterator();
            while (it.hasNext())
                System.out.println("Thread " + m_threadNumber + ": "
                        + new String(it.next().message()));
            System.out.println("Shutting down Thread: " + m_threadNumber);
        }
    
    }
    
    展开全文
  • java源码包---java 源码 大量 实例

    千次下载 热门讨论 2013-04-18 23:15:26
     Java非对称加密源程序代码实例,本例中使用RSA加密技术,定义加密算法可用 DES,DESede,Blowfish等。  设定字符串为“张三,你好,我是李四”  产生张三的密钥对(keyPairZhang)  张三生成公钥(publicKeyZhang...
  • 100个Java经典编程实例代码 h好东西
  • java完整项目-网上商城实例

    热门讨论 2009-08-17 21:57:15
    此资源为完整JAVA项目开发,很全,代码,数据库都有。
  • Java 技术篇-使用IDEA开发java代码实例演示,IntelliJ IDEA的安装与使用 接下来开始要创建项目名了。 Java 标准命名规范: 项目名全部小写。 包名全部小写。 类名首字母大写,一般都是使用驼峰式命名。 变量名、方法...
  • JAVA上百实例源码以及开源项目

    千次下载 热门讨论 2016-01-03 17:37:40
     Java非对称加密源程序代码实例,本例中使用RSA加密技术,定义加密算法可用 DES,DESede,Blowfish等。  设定字符串为“张三,你好,我是李四”  产生张三的密钥对(keyPairZhang)  张三生成公钥(publicKeyZhang...
  • java项目整合Axis1.4webservice搭建实例】服务端代码
  • java.net.Inet4Address 代码实例

    千次阅读 2017-10-25 21:42:15
    java.net.Inet4Address 代码实例 以下是展示如何使用java.net.Inet4Address的最佳示例。 我们使用了代码质量辨别算法从开源项目中提取出了最佳的优秀示例。 实例 1 package io.hydrosphere.mist.utils ...
  • java项目开发10例源代码

    千次下载 热门讨论 2014-03-18 08:36:10
    java实例10个 源代码 供大家参考 从桌面软件到网页设计到企业项目,手游都有,可能有些已过时,但学习一下也好的

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 392,126
精华内容 156,850
关键字:

java小项目代码实例

java 订阅