0

0

Java并发基础总结

伊谢尔伦

伊谢尔伦

发布时间:2016-12-05 11:38:25

|

1388人浏览过

|

来源于php中文网

原创

并发是一种能并行运行多个程序或并行运行一个程序中多个部分的能力。如果程序中一个耗时的任务能以异步或并行的方式运行,那么整个程序的吞吐量和可 交互性将大大改善。现代的pc都有多个cpu或一个cpu中有多个核,是否能合理运用多核的能力将成为一个大规模应用程序的关键。

线程基本使用

编写线程运行时执行的代码有两种方式:一种是创建Thread子类的一个实例并重写run方法,第二种是创建类的时候实现Runnable接口。当然,实现 Callable 也算是一种方式,Callable和Future结合实现可以实现在执行完任务后获取返回值,而Runnable和Thread方式是无法获取任务执行后的结果的。

public class ThreadMain {
    public static void main(String[] args) {
        MyThread myThread = new MyThread();        
        new Thread(myThread).start();        
        new MyThreas2().start();
    }
}// 第一种方式,实现Runable接口class MyThread implements Runnable {
    @Override    
    public void run() {
        System.out.println("MyThread run...");
    }
}// 第二种方式,继承Thread类,重写run()方法class MyThreas2 extends Thread {
    @Override    
    public void run() {
        System.out.println("MyThread2 run...");
    }
}

一旦线程启动后start()方法会立即返回,而不会等待run()方法执行完毕后返回,就好像run方法是在另外一个cpu上执行一样。

注意:创建并运行一个线程所犯的常见错误是调用线程的run()方法而非start()方法,如下所示:

立即学习Java免费学习笔记(深入)”;

Thread newThread = new Thread(MyRunnable());
newThread.run();  //should be start();

起初你并不会感觉到有什么不妥,因为run()方法的确如你所愿的被调用了。但是,事实上,run()方法并非是由刚创建的新线程所执行的,而是当前线程所执行了。也就是被执行上面两行代码的线程所执行的。想要让创建的新线程执行run()方法,必须调用新线程的start方法。

Callable和Future结合实现实现在执行完任务后获取返回值:

public static void main(String[] args) {
    ExecutorService exec = Executors.newSingleThreadExecutor();
    Future future = exec.submit(new CallTask());
    System.out.println(future.get());
}class CallTask implements Callable {
    public String call() {        
    return "hello";
    }
}

给线程设置线程名:

MyTask myTask = new MyTask();
Thread thread = new Thread(myTask, "myTask thread");
thread.start();
System.out.println(thread.getName());

当创建一个线程的时候,可以给线程起一个名字。它有助于我们区分不同的线程。

volatile

在多线程并发编程中synchronized和Volatile都扮演着重要的角色,Volatile是 轻量级的 synchronized ,它在多处理器开发中保证了共享变量的“可见性”。可见性的意思是当一个线程修改一个共享变量时,另外一个线程能读到这个修改的值。它在某些情况下比synchronized的开销更小,但是volatile不能保证变量的原子性。

volatile变量进行写操作时(汇编下有lock指令),该lock指令在多核系统下有2个作用:

将当前CPU缓存行写回系统内存。 
这个写回操作会引起其他CPU缓存了改地址的数据失效。 
多CPU下遵循缓存一致性原则,每个CPU通过嗅探在总线上传播的数据来检查自己的缓存值是否过期了,当发现缓存对应的内存地址被修改,将对应缓存行设置为无效状态,下次对数据操作会从系统内存重新读取。更多volatile知识请点击 深入分析Volatile的实现原理 。

synchronized

在多线程并发编程中Synchronized一直是元老级角色,很多人都会称呼它为重量级锁,但是随着Java SE1.6对Synchronized进行了各种优化之后,有些情况下它并不那么重了。

Java中每一个对象都可以作为锁,当一个线程试图访问同步代码块时,它首先必须得到锁,退出或抛出异常时必须释放锁。

对于同步方法,锁是当前实例对象。 
对于静态同步方法,锁是当前对象的Class对象。 
对于同步方法块,锁是Synchonized括号里配置的对象。 
synchronized关键字是不能继承的,也就是说基类中的synchronized方法在子类中默认并不是synchronized的。当线程试图访问同步代码块时,必须先获得锁,退出或抛出异常时释放锁。Java中每个对象都可以作为锁,那么锁存在哪里呢?锁存在Java对象头中,如果对象是数组类型,则虚拟机用3个word(字宽) 存储对象头,如果对象是非数组类型,则用2字宽存储对象头。更多synchronized知识请点击 Java SE1.6中的Synchronized 。

线程池

线程池负责管理工作线程,包含一个等待执行的任务队列。线程池的任务队列是一个Runnable集合,工作线程负责从任务队列中取出并执行Runnable对象。

E购-新零售系统
E购-新零售系统

“米烁云货宝”,是一款基于云计算的Saas模式新零售系统。以互联网为基础,通过大数据、人工智能等先进技术,对商品的生产、流通、销售、服务等环节转型升级改造,进而重塑业态结构与生态圈。并对线上交易运营服务、线下体验购买及现代物流进行深度融合,所形成的零售新模式。

下载
ExecutorService executor  = Executors.newCachedThreadPool();
  for (int i = 0; i < 5; i++) {
    executor.execute(new MyThread2());
}executor.shutdown();

Java通过Executors提供了4种线程池:

newCachedThreadPool:创建一个可缓存线程池,对于新任务如果没有空闲线程就新创建一个线程,如果空闲线程超过一定时间就会回收。

newFixedThreadPool:创建一个固定数量线程的线程池。

newSingleThreadExecutor:创建一个单线程的线程池,该线程池只用一个线程来执行任务,保证所有任务都按照FIFO顺序执行。

newScheduledThreadPool:创建一个定长线程池,支持定时及周期性任务执行。

以上几种线程池底层都是调用ThreadPoolExecutor来创建线程池的。

ThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue workQueue)

corePoolSize(线程池的基本大小):当提交一个任务到线程池时,线程池会创建一个线程来执行任务,即使其他空闲的基本线程能够执行新任务也会创建线程,等到需要执行的任务数大于线程池基本大小时就不再创建。如果调用了线程池的prestartAllCoreThreads方法,线程池会提前创建并启动所有基本线程。

maximumPoolSize(线程池最大大小):线程池允许创建的最大线程数。如果队列满了,并且已创建的线程数小于最大线程数,则线程池会再创建新的线程执行任务。值得注意的是如果使用了无界的任务队列这个参数就没什么效果。

keepAliveTime(线程活动保持时间):线程池的工作线程空闲后,保持存活的时间。所以如果任务很多,并且每个任务执行的时间比较短,可以调大这个时间,提高线程的利用率。

TimeUnit(线程活动保持时间的单位):可选的单位有天(DAYS),小时(HOURS),分钟(MINUTES),毫秒(MILLISECONDS),微秒(MICROSECONDS, 千分之一毫秒)和毫微秒(NANOSECONDS, 千分之一微秒)。,可以选择的阻塞队列有以下几种:

workQueue(任务队列):用于保存等待执行的任务的阻塞队列。

ArrayBlockingQueue:是一个基于数组结构的有界阻塞队列,此队列按 FIFO(先进先出)原则对元素进行排序。

LinkedBlockingQueue:一个基于链表结构的阻塞队列,此队列按FIFO (先进先出) 排序元素,吞吐量通常要高于ArrayBlockingQueue。静态工厂方法Executors.newFixedThreadPool()使用了这个队列。

SynchronousQueue:一个不存储元素的阻塞队列。每个插入操作必须等到另一个线程调用移除操作,否则插入操作一直处于阻塞状态,吞吐量通常要高于LinkedBlockingQueue,静态工厂方法Executors.newCachedThreadPool使用了这个队列。

PriorityBlockingQueue:一个具有优先级得无限阻塞队列。

当提交新任务到线程池时,其处理流程如下:

1.先判断基本线程池是否已满?没满则创建一个工作线程来执行任务,满了则进入下个流程。 
2.其次判断工作队列是否已满?没满则提交新任务到工作队列中,满了则进入下个流程。 
3.最后判断整个线程池是否已满?没满则创建一个新的工作线程来执行任务,满了则交给饱和策略来处理这个任务。

相关文章

java速学教程(入门到精通)
java速学教程(入门到精通)

java怎么学习?java怎么入门?java在哪学?java怎么学才快?不用担心,这里为大家提供了java速学教程(入门到精通),有需要的小伙伴保存下载就能学习啦!

下载

相关标签:

本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

热门AI工具

更多
DeepSeek
DeepSeek

幻方量化公司旗下的开源大模型平台

豆包大模型
豆包大模型

字节跳动自主研发的一系列大型语言模型

通义千问
通义千问

阿里巴巴推出的全能AI助手

腾讯元宝
腾讯元宝

腾讯混元平台推出的AI助手

文心一言
文心一言

文心一言是百度开发的AI聊天机器人,通过对话可以生成各种形式的内容。

讯飞写作
讯飞写作

基于讯飞星火大模型的AI写作工具,可以快速生成新闻稿件、品宣文案、工作总结、心得体会等各种文文稿

即梦AI
即梦AI

一站式AI创作平台,免费AI图片和视频生成。

ChatGPT
ChatGPT

最最强大的AI聊天机器人程序,ChatGPT不单是聊天机器人,还能进行撰写邮件、视频脚本、文案、翻译、代码等任务。

相关专题

更多
C++ 设计模式与软件架构
C++ 设计模式与软件架构

本专题深入讲解 C++ 中的常见设计模式与架构优化,包括单例模式、工厂模式、观察者模式、策略模式、命令模式等,结合实际案例展示如何在 C++ 项目中应用这些模式提升代码可维护性与扩展性。通过案例分析,帮助开发者掌握 如何运用设计模式构建高质量的软件架构,提升系统的灵活性与可扩展性。

14

2026.01.30

c++ 字符串格式化
c++ 字符串格式化

本专题整合了c++字符串格式化用法、输出技巧、实践等等内容,阅读专题下面的文章了解更多详细内容。

9

2026.01.30

java 字符串格式化
java 字符串格式化

本专题整合了java如何进行字符串格式化相关教程、使用解析、方法详解等等内容。阅读专题下面的文章了解更多详细教程。

12

2026.01.30

python 字符串格式化
python 字符串格式化

本专题整合了python字符串格式化教程、实践、方法、进阶等等相关内容,阅读专题下面的文章了解更多详细操作。

4

2026.01.30

java入门学习合集
java入门学习合集

本专题整合了java入门学习指南、初学者项目实战、入门到精通等等内容,阅读专题下面的文章了解更多详细学习方法。

20

2026.01.29

java配置环境变量教程合集
java配置环境变量教程合集

本专题整合了java配置环境变量设置、步骤、安装jdk、避免冲突等等相关内容,阅读专题下面的文章了解更多详细操作。

18

2026.01.29

java成品学习网站推荐大全
java成品学习网站推荐大全

本专题整合了java成品网站、在线成品网站源码、源码入口等等相关内容,阅读专题下面的文章了解更多详细推荐内容。

19

2026.01.29

Java字符串处理使用教程合集
Java字符串处理使用教程合集

本专题整合了Java字符串截取、处理、使用、实战等等教程内容,阅读专题下面的文章了解详细操作教程。

3

2026.01.29

Java空对象相关教程合集
Java空对象相关教程合集

本专题整合了Java空对象相关教程,阅读专题下面的文章了解更多详细内容。

6

2026.01.29

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
Kotlin 教程
Kotlin 教程

共23课时 | 3万人学习

C# 教程
C# 教程

共94课时 | 8万人学习

Java 教程
Java 教程

共578课时 | 53.7万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号