Thinking in java并发
2016-05-16 07:10
405 查看
定义任务
线程可以驱动任务,我们通过实现 Runnable 接口来提供,需要实现 Runnable 接口的 run() 方法。package com.kevindai.concurrency; public class LiftOff implements Runnable{ protected int countDown = 10; private static int taskCount = 0; private final int id = taskCount++; public LiftOff() { } public LiftOff(int countDown) { super(); this.countDown = countDown; } public String status() { return "#" + id + "(" + (countDown > 0 ? countDown : "LiftOff") + "),"; } @Override public void run() { while (countDown-- > 0) { System.out.print(status()); Thread.yield();//线程调度器;建议进行线程调度 } System.out.println(); } public static void main(String[] args) { LiftOff liffOff = new LiftOff(); liffOff.run(); } }
输出:
我们也可以通过继承 Thread 类覆盖 run() 方法来实现线程类,但继承Thread类有一个缺点就是单继承,而实现Runnable接口则弥补了它的缺点,可以实现多继承。而且实现 Runnable 接口适合多线程共享资源,继承 Thread 类适合各个线程完成自己的任务,因为继承 Thread 类相当于每个线程有一份各自的资源,而实现 Runnable 还可以让多个线程共享一份代码。
Thread类
在代码中一般的使用方式都是将 Runnable 对象转变为任务的过程交给给一个 Thread 构造器。package com.kevindai.concurrency; public class BasicThreads { public static void main(String[] args) { Thread th = new Thread(new LiftOff()); th.start(); System.out.println("waiting for LiftOff"); } }
Thread 构造器只需要一个 Runnable 对象。调用 Thread 对象的 start() 方法为该线程执行必须的初始化操作,然后内部调用 Runnable 的 run() 方法。
本Markdown编辑器使用[StackEdit][6]修改而来,用它写博客,将会带来全新的体验哦:
使用 Executor
使用线程池来分配线程package com.kevindai.concurrency; import java.util.concurrent.ExecutionException; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.Future; public class CachedThreadPool { public static void main(String[] args) throws InterruptedException, ExecutionException { ExecutorService exec = Executors.newCachedThreadPool(); for(int i = 0;i < 5;i++){ exec.execute(new LiftOff()); } exec.shutdown(); } }
线程池主要的实现主要包括以下几种:
CacheThreadPool:为每个任务都创建一个线程
FixedThreadPool:一次性预先分配好固定数量的线程
SingleThreadExecutor:线程数唯一,提交多个任务会排队等候
ScheduledThreadPool:创建一个定长线程池,支持定时及周期性任务执行。
从任务中产生返回值
如果我们希望任务完成时能够返回一个值,那么可以实现 Callable 接口而不是 Runnable 接口,实现 Callable 接口要求覆盖 Call() 方法。(用此方法使项目的中一个功能的运行速度提高了5倍以上)package com.kevindai.concurrency; import java.util.concurrent.ExecutionException; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.Future; public class CachedThreadPool { @SuppressWarnings("unchecked") public static void main(String[] args) throws InterruptedException, ExecutionException { ExecutorService exec = Executors.newCachedThreadPool(); Future<?> f1 = null; String str1 = ""; for(int i = 0;i < 5;i++){ f1 = exec.submit(new TestReturn("test1", "test2", "", "", "", "", "", "")); str1 += f1.get(); } System.out.println(str1); } } package com.kevindai.concurrency; import java.util.concurrent.Callable; @SuppressWarnings("rawtypes") public class TestReturn implements Callable{ private String originalPathList; private String dhsList; private String originalIP; private String originalDirPath; private String originalType; private String idsList; private String isMedia; private String type; public TestReturn(String originalPathList, String dhsList, String originalIP, String originalDirPath, String originalType, String idsList, String isMedia, String type) { super(); this.originalPathList = originalPathList; this.dhsList = dhsList; this.originalIP = originalIP; this.originalDirPath = originalDirPath; this.originalType = originalType; this.idsList = idsList; this.isMedia = isMedia; this.type = type; } @Override public Object call() throws Exception { return originalPathList + dhsList.toString(); } }
优先级
线程的优先级将该线程的重要性传递给了调度器。调度器会倾向于让优先级高的线程先使用方法:Thread.currentThread().setPriority(priority);
自己测试了没测试出什么效果,不写例子了,知道用法就好了
加入线程
一个线程可以在其他线程之上调用 join() 方法,其效果是等待一段时间直到第二个线程结束才继续执行。join() 调用时可以携带超时参数。package com.kevindai.concurrency.join; public class Sleeper extends Thread { private int duration; public Sleeper(String name,int sleepTime){ super(name); duration = sleepTime; start(); } public void run(){ try { sleep(duration); } catch (InterruptedException e) { System.out.println(getName() + " was interrupted." + "isInterrupted():" + isInterrupted()); return; } System.out.println(getName() + " has awakened"); } } package com.kevindai.concurrency.join; public class Joiner extends Thread { private Sleeper sleeper; public Joiner(String name,Sleeper sleeper){ super(name); this.sleeper = sleeper; start(); } public void run(){ try { sleeper.join(); } catch (InterruptedException e) { System.out.println("Interrupted"); } System.out.println(getName() + " join completed"); } } package com.kevindai.concurrency.join; public class Joining { public static void main(String[] args) { Sleeper sleepy = new Sleeper("Sleepy", 1500), grumpy = new Sleeper("Grumpy", 1500); Joiner dopey = new Joiner("Dopey", sleepy), doc = new Joiner("Doc", grumpy); grumpy.interrupt(); } }
输出:
共享资源
相关文章推荐
- PAT-Java-1017. A除以B (20)
- Spring学习(一)---IoC介绍
- Java EE
- activemq使用系列: spring与activemq的整合
- java.lang.ClassNotFoundException: org.springframework.web.context.ContextLoaderListener问题
- [解决]java.io.IOException: Cannot obtain block length for LocatedBlock
- JAVA学习总结八
- java使用new Date()和System.currentTimeMillis()获取当前时间戳
- JAVA学习总结七
- Spring学习(一)---IoC介绍
- 再谈如何将android studio项目转换成eclipse
- JAVA vim 开发环境配置
- ThreadPoolExecutor机制
- 各种排序算法的分析与实现 java
- 框架 day29 Struts2-上传,下载,OGNL与Struts2的结合(值栈与ActionContext),Struts2标签,Token机制
- java初级阶段学习总结
- NoClassDefFoundError: javax/servlet/jsp/jstl/core/Config
- 3.JAVA中常见的英文
- java输出换行的标准姿势"line.separator"
- 关于java ee, ide,jms,jmx,jndi等专业术语的全称问题