`
JackyCheng2007
  • 浏览: 253587 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

深入学习 Java concurrent - 多线程

    博客分类:
  • Java
阅读更多
我觉得要清理一下关于进程和线程的基本概念。

首先就是进程。

什么是进程呢?简单的说就是cpu的一个执行过程,在这个过程中,os为它分配独立的内存空间,这样就保证不被别的进程影响。单任务的os就是说多个进程间只能顺序的执行,也就是说多个事情只能一件一件的做。那么多任务的os支持多个进程交叉同时执行。为什么要这样呢?学过统筹方法吗?如果没有,你是不是经常同事做两件事情?比如在打开电脑的同时,你在吃早点。cpu也是一样的,比如当cpu通过打印机打印的时候,让打印机自己忙去,cpu还可以同时干点别的事情。这样就理解多进程的原因了。


那么什么是多线程呢?

线程也是一个执行过程,只是比进程的粒度更小。在一个进程中可以同时多个线程交叉进行。不同的是,线程并没有向进程那样享有单独的地址空间,而是给你共享这个进程所在的地址空间。

那么为什么还要划分比进程粒度更小的执行过程呢?
在现在os中,支持线程调度,那么线程就成了任务调度的单位。不过进程确实资源分配的单位。
多进程系统可以同时运行多个进程,但是每一个进程只能有一个线程。多线程系统允许运行多个线程,但是统一进程内的所有的线程共享相同的地址空间和系统资源。

不管多进程也好,多线程也好都是为了并发。并发的好处除了加快处理任务外,还有一个好处就是为了更好的设计。比如当你copy文件的时候,你不想copy了,你可以中途取消,这就是并发带来的好处,这个需求是很简单直观的,但如果没有并发技术的支持,在计算机技术里面是很难实现的。没有并发,计算机就会变的一根筋。

在Java里面又是怎么做的呢?
首先,既然是多任务同时进行,得先定义任务。在Java里面定义一个任务很简单,只要让这个类实现Runnable 接口。同时实现这个接口的唯一的一个run()方法。这个有点类似command模式。在run方法里面定义这个任务要完成的事情。
public class HelloTask implements Runnable {
	@Override
	public void run() {
		System.out.println("I am a task running");
	}
	
	public static void main(String[] args) {
		HelloTask task =  new HelloTask();
		task.run();
                System.out.println("I am in main");
	}
}

你肯定知道输出是什么,这里句话肯定会顺序输出:
引用

I am a task running
I am in main

这个Runnable接口实在没有什么特别的:
public interface Runnable {
    public abstract void run();
}


你看,和普通的接口有什么区别?在main方法里面调用,就和一般的类没有什么区别。只是它总是和多线程绑在一起,才显得神秘。既然没有什么特别的,那就怎么让它实现并发呢?那就得把这个task挂在一个线程上:
public class HelloTask implements Runnable {
	@Override
	public void run() {
		System.out.println("I am a task running");
	}
	
	public static void main(String[] args) {
		HelloTask task =  new HelloTask();
		Thread t = new Thread(task);
		t.start();
		System.out.println("I am in main");
	}
}

你认为上面的代码会输出什么?
引用

I am in main
I am a task running

这两句话,不一定哪个先输出。这就是并发导致的,当调用start方法的时候,就会启动一个新的线程和当前正在运行的主线程并发执行,他们会争抢cpu,看谁快。所以输出的顺序无法预知。
你因该注意到了,在构造Thread的时候我们把task传给了他,那时因为它接收Runnable接口。他会在start方法之后调用这个参数对象的run方法。这是不是command模式?
所以说,任何类都可以放在Thread里面去并发运行,只要实现Runnable接口,编写自己的run方法,高速线程,你想干什么。说道这里视乎线程也没有那么什么了,只是他会并发的调用task的run方法。
从Jdk5以后,jdk给我们提供过来更方便的多线程实现工具包java.util.concurrent提供了一些有用的并发编程框架和工具类。

Executor
执行器,是一个简单的标准化的接口,提供线程似的子系统,比如线程池,异步IO以及轻量级的任务框架。

public class HelloTask implements Runnable {
	private static int taskCount = 0;
	private final int id = taskCount++;

	@Override
	public void run() {
		System.out.println("I am a task running: " + id);
	}

	public static void main(String[] args) {
		ExecutorService exec = Executors.newCachedThreadPool();
		for (int i = 0; i < 5; i++) {
			exec.execute(new HelloTask());
		}
                exec.shutdown();
		System.out.println("I am in main");
	}
}

有了这个包,你不用再自己管理Thread的生命周期。而是托管给ExecutorService。ExecutorService可以帮你调度并发任务,你只要调用它的execute方法,你一下他的execute方法,也是按照Command模式设计的。ExecutorService 也是一个接口,并且实现了Executor接口。除了包含Executor方法外,ExecutorService 还定义了其他一些方法:
public interface ExecutorService extends Executor {
    void shutdown();
    <T> Future<T> submit(Callable<T> task);
    <T> List<Future<T>> invokeAll(Collection<? extends Callable<T>> tasks)
        throws InterruptedException;
    ...
}
public interface Executor {
    void execute(Runnable command);
}

Executors是一个静态工厂类,提供了很多创建各种ExecutorService的工厂方法。

线程池
如果某些资源的创建比较费劲,也就耗费时间和资源,那就得考虑用pool也就是池来保存一些预先创建好的资源,用的时候拿来用,用完放回去。典型的有jdbc连接池。线程池也算一个。
Executors就提供了各种各项的线程池共你选择:
1. CachedThreadPool
这种线程池会不停的为你创建新的线程,只要当前pool里面没有可用的。这个其实很危险,很容易耗尽你的资源。
2. FixedThreadPool
这个线程池的策略是为你保持指定大小的线程数,这个还算比较好控制,任务比线程数多的时候就排队等候。
3. SingleThreadExecutor
其实就是固定大小为一的FixedThreadPool。这个策略也很有用。当你只想用一个线程完成一系列任务的时候,就可以用它为你维护你可以任务队列,他会帮你一次顺序调用。完成一件,在做下一件。




分享到:
评论

相关推荐

    concurrent-1.3.4-sources.jar

    通过学习`concurrent-1.3.4-sources.jar`中的源代码,开发者不仅可以深入理解Java并发编程的基本原理,还能学习到如何设计和实现高效、安全的并发程序。同时,这个库的源代码也是研究并发算法和数据结构的良好实例,...

    深入学习:Java多线程编程

    《深入学习:Java多线程编程》是一本专注于Java并发技术的专业书籍,旨在帮助开发者深入理解和熟练运用Java中的多线程编程。Java多线程是Java编程中的核心部分,尤其在现代高性能应用和分布式系统中不可或缺。理解并...

    Java 实例 - 查看线程优先级源代码+详细指导教程.zip

    这个压缩包“Java 实例 - 查看线程优先级源代码+详细指导教程.zip”包含了一个关于如何查看和理解Java线程优先级的实例源代码和教学材料,对于深入学习Java多线程编程非常有帮助。 在Java中,线程的优先级是由`...

    JAVA-JavaThreadProgramming-Sams.zip_JAVA 设计_java 多线程_java 线程_多线程

    `java.util.concurrent`包还包含了并发集合,如ConcurrentHashMap、CopyOnWriteArrayList等,它们在多线程环境下提供了高效且线程安全的操作。ExecutorService和Future接口为线程池和异步任务执行提供了抽象,使得...

    Java 实例 - 获取线程id源代码+详细指导教程.zip

    通过深入理解这些概念和实践,你可以更好地进行多线程编程,提高程序的并发性能和稳定性。在学习过程中,可以参考提供的"Java实例 - 获取线程id源代码+详细指导教程.rar"压缩包文件,里面包含的源代码和教程将有助于...

    Java-concurrentMap-内存模型深入分析-HotCode

    Java内存模型定义了线程之间的共享变量访问规则,确保在多线程环境下正确地同步数据。JMM规定了内存的可见性、原子性和有序性,这对于理解`concurrentMap`的工作机制至关重要。例如,`ConcurrentHashMap`使用了分段...

    java concurrent 精简源码

    这个“java concurrent 精简源码”资源很可能会包含上述概念的实际应用示例,通过学习和分析这些代码,你可以深入理解Java并发编程的精髓,并能更好地应用于实际项目中。在研究时,建议结合Java官方文档和相关的书籍...

    【IT十八掌徐培成】Java基础第21天-05.URL-多线程下载-断点续传-Properties.zip

    Java提供了`java.lang.Thread`类来创建和管理线程,同时`java.util.concurrent`包提供了高级并发工具如`ExecutorService`和`Future`,使得多线程的管理和控制更为便捷。在实现多线程下载时,一般会将大文件分成多个...

    深入浅出 Java 多线程.pdf_java_

    Java多线程是Java编程中的核心概念,尤其在如今并发性能至关重要的软件开发中,它的重要性不言而喻。...深入学习这一部分将极大地提升Java程序员的设计能力和解决问题的能力,使得能够编写出更加健壮、高效的并发程序。

    Java实现多线程下载源代码

    首先,我们来深入理解Java中的多线程。在Java中,线程是程序执行的最小单位,通过创建多个线程,可以实现并发执行任务。多线程下载就是利用这个特性,创建一个线程来处理每个文件的部分下载。Java提供了多种创建线程...

    【IT十八掌徐培成】Java基础第21天-04.URL-多线程下载-暂停操作.zip

    在本课程“【IT十八掌徐培成】Java基础第21天-04.URL-多线程下载-暂停操作”中,讲师徐培成深入讲解了Java在处理网络资源时的核心概念,特别是URL(统一资源定位符)、多线程下载以及如何实现下载过程中的暂停操作。...

    java多线程控制的赛跑程序

    通过这个赛跑程序,我们可以学习到如何在Java中有效地控制和管理多线程,理解并发编程的核心概念,并掌握处理线程安全、同步和通信的技巧。同时,这个程序还可能包含对性能优化、错误处理以及日志记录的实践。通过...

    Java实现的多线程下载工具

    Java实现的多线程下载工具是一种利用Java编程语言来提高文件下载效率的技术。在传统的单线程下载方式中,文件的下载过程由一...通过这个工具,不仅可以学习到Java的多线程编程,还能深入了解网络编程和文件处理等知识。

    基于java开发的多线程下载工具(源码)

    首先,让我们深入理解Java语言在多线程下载中的应用。Java提供了强大的多线程编程能力,通过`java.lang.Thread`类或`java.util.concurrent`包中的`ExecutorService`和`Future`接口,可以方便地创建和管理多个下载...

    【IT十八掌徐培成】Java基础第21天-06.URL-多线程下载-断点续传-文件实现.zip

    本课程“【IT十八掌徐培成】Java基础第21天-06.URL-多线程下载-断点续传-文件实现”深入讲解了Java中的几个关键概念和技术,包括URL、多线程下载、断点续传以及文件操作,这些都是构建高效、稳定网络应用程序的核心...

    java-Thread-study-summary.zip_java 多线程

    本资料“java-Thread-study-summary.zip”提供了一个深入学习Java多线程的综合指南,特别适合初学者进行实践操作。 1. **线程的创建** - 继承`Thread`类:创建一个新的类,该类继承自`Thread`,然后重写`run()`...

    java concurrent source code

    资深Java专家10年经验总结,全程案例式讲解,首本全面介绍Java多线程编程技术的专著 结合大量实例,全面讲解Java多线程编程中的...要学习这些热点技术,Java多线程技术避无可避。而本书将引领读者拿下该“技术高地”。

    贪吃蛇的多线程java程序

    贪吃蛇游戏是一款经典的计算机游戏,它通过控制蛇在有限的空间内不断移动并吞噬食物...通过理解和实践这个贪吃蛇的多线程Java程序,开发者可以深入学习Java的并发编程、线程同步以及GUI编程等多个方面,提升编程技能。

    基于Java的实例源码-多线程反射泛型及正则表达式学习笔记和源码.zip

    总的来说,这个压缩包中的源码和学习笔记是深入理解并熟练运用Java多线程、反射、泛型和正则表达式的宝贵资源。通过研究这些实例,开发者不仅可以巩固理论知识,还能提升实际编程技巧,从而在日常工作中编写出更加...

    JAVA多线程编程技术PDF

    在Java编程领域,多线程是一项至关重要的技术,它允许程序同时执行多个任务,从而提高系统资源的利用率和程序的响应速度...通过深入学习这份资料,开发者可以全面掌握Java多线程编程技术,提升程序的并发性能和稳定性。

Global site tag (gtag.js) - Google Analytics