Java 5.0 多线程编程实践-Java基础-Java-编程开发

Java 多线程编程基础(详细) Java多线程编程基础进程与线程多线程实现Thread类实现多线程Runnable接口实现多线程Callable接口实现多线程多线程运行状态多线程常用操作方法线程的命名和获取线程休眠线程中断线程强制执行线程让步线程优先级设定线程的同步和锁死线程同步处理线程死锁 进程与线程 进程与线程的基本认识 进程(Process):进程是程序的一次动态执行过程,它经历了从代码加载、执行、到执行完毕的一个完整过程;同时也是并发执行的程序在执行过程中分配和管理资源的基本单位,竞争计算机系统资源的基本单位。 线程(Thread 阅读详情
<script type="text/javascript" src="http://pagead2.googlesyndication.com/pagead/show_ads.js"> </script>

  Java5增加了新的类库并发集java.util.concurrent,该类库为并发程序提供了丰富的API多线程编程在Java 5中更加容易,灵活。本文通过一个网络服务器模型,来实践Java5的多线程编程,该模型中使用了Java5中的线程池,阻塞队列,可重入锁等,还实践了Callable, Future等接口,并使用了Java 5的另外一个新特性泛型。

  简介

  本文将实现一个网络服务器模型,一旦有客户端连接到该服务器,则启动一个新线程为该连接服务,服务内容为往客户端输送一些字符信息。一个典型的网络服务器模型如下:

  1. 建立监听端口。

  2. 发现有新连接,接受连接,启动线程,执行服务线程。 3. 服务完毕,关闭线程。

  这个模型在大部分情况下运行良好,但是需要频繁的处理用户请求而每次请求需要的服务又是简短的时候,系统会将大量的时间花费在线程的创建销毁。Java 5的线程池克服了这些缺点。通过对重用线程来执行多个任务,避免了频繁线程的创建与销毁开销,使得服务器的性能方面得到很大提高。因此,本文的网络服务器模型将如下:

  1. 建立监听端口,创建线程池。

  2. 发现有新连接,使用线程池来执行服务任务。

  3. 服务完毕,释放线程到线程池。

  下面详细介绍如何使用Java 5的concurrent包提供的API来实现该服务器。

  初始化

  初始化包括创建线程池以及初始化监听端口。创建线程池可以通过调用java.util.concurrent.Executors类里的静态方法newChahedThreadPool或是newFixedThreadPool来创建,也可以通过新建一个java.util.concurrent.ThreadPoolExecutor实例来执行任务。这里我们采用newFixedThreadPool方法来建立线程池。

ExecutorService pool = Executors.newFixedThreadPool(10);

  表示新建了一个线程池,线程池里面有10个线程为任务队列服务。

  使用ServerSocket对象来初始化监听端口。

private static final int PORT = 19527;
serverListenSocket = new ServerSocket(PORT);
serverListenSocket.setReuseAddress(true);
serverListenSocket.setReuseAddress(true);

  服务新连接

  当有新连接建立时,accept返回时,将服务任务提交给线程池执行。

while(true){
 Socket socket = serverListenSocket.accept();
 pool.execute(new ServiceThread(socket));
}

  这里使用线程池对象来执行线程,减少了每次线程创建和销毁的开销。任务执行完毕,线程释放到线程池。

  服务任务

  服务线程ServiceThread维护一个count来记录服务线程被调用的次数。每当服务任务被调用一次时,count的值自增1,因此ServiceThread提供一个increaseCount和getCount的方法,分别将count值自增1和取得该count值。由于可能多个线程存在竞争,同时访问count,因此需要加锁机制,在Java 5之前,我们只能使用synchronized来锁定。Java 5中引入了性能更加粒度更细的重入锁ReentrantLock。我们使用ReentrantLock保证代码线程安全。下面是具体代码:

private static ReentrantLock lock = new ReentrantLock ();
private static int count = 0;
private int getCount(){
 int ret = 0;
 try{
  lock.lock();
  ret = count;
 }finally{
  lock.unlock();
 }
 return ret;
}
private void increaseCount(){
 try{
  lock.lock();
   count;
 }finally{
  lock.unlock();
 }
}

  服务线程在开始给客户端打印一个欢迎信息

increaseCount();
int curCount = getCount();
helloString = "hello, id = " curCount "/r/n";
dos = new DataOutputStream(connectedSocket.getOutputStream());
dos.write(helloString.getBytes());

  然后使用ExecutorService的submit方法提交一个Callable的任务,返回一个Future接口的引用。这种做法对费时的任务非常有效,submit任务之后可以继续执行下面的代码,然后在适当的位置可以使用Future的get方法来获取结果,如果这时候该方法已经执行完毕,则无需等待即可获得结果,如果还在执行,则等待到运行完毕。

ExecutorService executor = Executors.newSingleThreadExecutor();
Future future = executor.submit(new TimeConsumingTask());
dos.write("let's do soemthing other".getBytes());
String result = future.get();
dos.write(result.getBytes());

  其中TimeConsumingTask实现了Callable接口

class TimeConsumingTask implements Callable {
 public String call() throws Exception {
  System.out.println("It's a time-consuming task, you'd better retrieve your result in the furture");
  return "ok, here's the result: It takes me lots of time to produce this result";
 }
}

  这里使用了Java 5的另外一个新特性泛型,声明TimeConsumingTask的时候使用了String做为类型参数。必须实现Callable接口的call函数,其作用类似与Runnable中的run函数,在call函数里写入要执行的代码,其返回值类型等同于在类声明中传入的类型值。在这段程序中,我们提交了一个Callable的任务,然后程序不会堵塞,而是继续执行dos.write("let's do soemthing other".getBytes());当程序执行到String result = future.get()时如果call函数已经执行完毕,则取得返回值,如果还在执行,则等待其执行完毕。

[1] [2]

Java基础之多线程编程 本文介绍了Java多线程编程的基础知识,包括多线程概念、线程生命周期(新建、就绪、运行、阻塞、死亡)、线程优先级设置,以及两种创建线程的方法(继承Thread类和实现Runnable接口)。通过示例代码演示了具体实现方式,并强调Runnable接口的灵活性优势。文章还提醒实际开发中需注意线程安全和同步机制,以避免死锁等问题。多线程技术能有效提升程序性能,但需要合理使用。 阅读详情

相关推荐

Java编程基础与实践案例分析

本文还有配套的精品资源,点击获取 简介:《Java基础案例教程-陈文兰》是面向初学者的编程教材,基于北京大学课程资源,强调通过实践案例教授Java核心概念和技术。本书详细介绍了Java环境搭建、基本语法、数据类型、控制流程、数组、字符串、方法、面向对象编程、异常处理、集合框架、输入输出流、多线程、文件操作、反射、枚举与注解、JNI接口、GUI编程以及网络编程等关键知识点。每...

weixin_34064233的博客 752

Java通用编程规范学习

Java编程规范学习命名注释排版变量和类型方法 说明:记录内容为平常代码中常用到的且容易忽视的内容 命名 变量命名:\w{2,64},建议不超过31个 不应使用特殊前缀或后缀。例如下面是不合适的:name_, mName, s_name 和 kName 包名称小写以点号隔开,包名允许有数字 方法命名如图: 不要使用魔鬼数字,用有意义的常量代替。SQL或日志的字符串,不应视为“魔鬼数字”,不需定义为字符串常量;不应该取NUM_FIVE = 5或NUM_5 = 5这样的魔鬼常量。 避免使用否定的布尔变量名,

weixin_38370441的博客 5252

Java SE5.0入门到实践全套教程

Java作为一门深受开发者喜爱的编程语言,在企业级应用、移动应用、云服务等多个领域中都扮演着重要的角色。本章节主要为初学者提供了一个全面的Java基础教程,涵盖Java语言的基本概念、语法以及应用环境,帮助他们快速入门。从安装JDK、编写第一个Hello World程序开始,逐步深入理解Java的变量、控制结构、数组和字符串处理等基础知识点。本章内容不仅为读者提供了扎实的基础,也为后续章节中的高级概念和编程技巧的学习打下了坚实的基础。// 示例代码:第一个Java程序");

weixin_36444661的博客 850

【笔记81】并发工具优于 wait 和 notify

本书第 1 版中专门用了一个条目来说明如何正确地使用wait和notify。它提出的建议仍然有效,并且在本条目的最后也对此做了概述,但是这条建议现在远远没有之前那么重要了。这是因为几乎没有理由再使用wait和notify了。自从 Java 5 发行版本开始, Java 平台就提供了更高级的并发工具,它们可以完成以前必须在wait和notify上手写代码来完成的各项工作。既...

u013773608的博客 553

JDK5中的并发(多线程)

JDK 5.0 是用 Java 语言创建高可伸缩的并发应用程序的主要步骤。JVM 已经进行了改进,允许类利用硬件级别支持并发,并且提供了一组丰富的新并发构造块,使开发并发应用程序更加容易。 <br><br>本教程将介绍 JDK 5.0 提供的用于并发的新实用程序类,并通过与现有并发原语(synchronized、wait() 和 notify())相比较,说明这些类如何提高了可伸缩性。 <br>

Java 高并发多线程编程系列案例代码

Java 高并发多线程编程系列案例代码 & 教程 & 面试题集锦! !! 包括但不限于线程安全性, atomic包下相关类、CAS原理、Unsafe类、synchronized关键字等的使用及注意事项,

JDK1.8并发包中的类

Lock java.util.concurrent.locks.AbstractOwnableSynchronizer 抽象类: java.util.concurrent.locks.AbstractQueuedLongSynchronizer AbstractQueuedSynchronize的64位实现,完全一致。 java.util.concurre...

demon7552003的小本本 1887

java5 并发包 (concurrent)思维导图

并发包总结 思维导图 concurrent

Java高级编程——多线程(JDK5新增创建线程方式Callable,线程池)

创建线程的第三、四种方式一、实现Callable接口1.1与Runnable相比1.2实现步骤二、使用线程池2.12.1.1 背景2.1.2 思路2.1.3 好处2.2 创建线程池2.2.1 Executors.newFixedThreadPool(int n);2.3 管理线程池2.3.1 设置线程池属性 一、实现Callable接口 1.1与Runnable相比 与Runnable相比Callable功能更加强大 相比于run()方法,call()可以有返回值 方法可以抛出异常,被外面的操作捕获 支

ou_yang_mu_ling的博客 787

不到200块!手把手教你用ZYNQ7010和AD9363攒一台自己的开源SDR硬件(附BOM清单)

本文详细介绍了如何用不到200元的预算,基于ZYNQ7010 FPGA和AD9363射频芯片打造一台功能完备的开源SDR硬件平台。从核心组件选型、PCB设计到焊接调试,提供全流程实战指南,特别适合预算有限的硬件爱好者和创客群体探索无线通信世界。

weixin_26854829的博客 483

Word多级标题出现黑块的解决思路(word 数字必须介于1-1638之间)

遇到多级目录出现黑块问题,看到一篇博客完美解决,在此记录。

AI_Optimization的博客 3716

Java 5.0多线程编程

v/:* {behavior:url(#default#VML);}o/:* {behavior:url(#default#VML);}w/:* {behavior:url(#default#VML);}.shape {behavior:url(#default#VML);} Mike Li LiTao 2 10650 2006-06

javachannel的专栏 1万+

AS5600磁编码器选型与安装避坑指南:磁铁形状、间隙距离到底怎么选?(附实测数据)

本文详细解析了AS5600磁编码器的选型与安装要点,包括磁铁形状、间隙距离等关键参数的选择,并附有实测数据支持。特别针对Arduino和I2C接口的应用场景,提供了硬件选型和机械安装的实用指南,帮助开发者避免常见陷阱,提升系统精度和稳定性。

weixin_27038245的博客 290

⚡️⚡️Java多线程编程的高效、安全实践

Java作为一门强大而广泛使用的编程语言,多线程编程是其重要的特性之一。在本文中,我们将深入探讨Java多线程编程与并发控制的方方面面。我们将从多线程的基本概念入手,了解多线程编程的优势和挑战。然后,我们会介绍Java中创建和管理线程的几种方式,并探讨如何避免常见的并发问题。通过本文的学习,将能够优雅地掌控Java多线程编程,构建高效、稳定的并发应用。

沉淀所学,分享所思,让热爱与成长同行。商务记录AI实战经验,助力开发者快速成长。 热爱AI,希望做出有影响力的技术成果。 技术点亮生活,分享连接价值与机会。 专注AI落地实战,陪你走好技术每一步。 7091

对西安交大轴承数据集XJTU-SY_Bearing_Datasets进行读取和处理:

故障诊断,对西安交大轴承数据集XJTU-SY_Bearing_Datasets进行读取和处理

qq_44757503的博客 6061

Matlab实现POD本征正交分解数据降维模型

近年来,随着大数据时代的到来,各种复杂的工程问题产生了海量的高维数据,如何有效降维、提取数据中的关键信息成为了众多领域中的重要问题。在传统的数据降维方法中,PCTFA(主成分分析)是一种典型的统计方法,然而对于流体动力学等非线性问题,PCTFA在处理时可能失去部分物理意义,难以捕捉到系统的复杂性。在降维过程中,POD提取的主要特征通常是一组复杂的正交基函数,如何将这些结果有效地转化为直观且易于理解的物理意义,特别是在实际应用中,对该特征的理解和分析,依然是一个重要的课题。本项目的扩展性也得到了有效体现。

优质创作者: 人工智能技术领域 对于有一定基础的 MATLAB和Python带具体需求都可以详谈 MATLAB和Python可以提供代码调试服务加油 谢谢 你的鼓励是我前行的动力 谢谢支持 加油 谢谢 1216

Java5 多线程实践

Java5增加了新的类库并发集java.util.concurrent,该类库为并发程序提供了丰富的API多线程编程在Java 5中更加容易,灵活。本文通过一个网络服务器模型,来实践Java5的多线程编程,该模型中使用了Java5中的线程池,阻塞队列,可重入锁等,还实践了Callable, Future等接口,并使用了Java 5的另外一个新特性泛型。本文将实现一个网络服务器模型,一旦有客户端

键者天行 8860

Cursor Agent模式下如何优雅切换conda环境运行Python脚本?3种实用方法实测

本文针对Cursor Agent模式下运行Python脚本时环境错配的痛点,实测了三种优雅切换conda环境的实用方法。通过Shell全局配置、项目级.cursorrc文件定制以及对话中直接指令,开发者可以确保AI助手在正确的虚拟环境中执行代码,从而提升开发效率和协作流畅度。

redis7keeper的博客 598

Java 5.0 多线程编程实践

<!--google_ad_client = "pub-5005299000903884";google_ad_width = 728;google_ad_height = 90;google_ad_format = "728x90_as";google_ad_type = "text_image";google_ad_channel ="";google_color_

1034

Linux C/C++ or 嵌入式面试之《C/C++笔面试系列》(10) C++ 前置后置增减运算符重载形式与比较

C语言的++、–运算符在此不讨论。 文章目录1、前置后置增减运算符重载的形式2、前置和后置运算符的性能比较 1、前置后置增减运算符重载的形式 自增运算符“++”和自减运算符“–”分别包含两个版本。即运算符前置形式(如 ++x)和运算符后置形式(如 x++),这两者进行的操作是不一样的。因此,当我们在对这两个运算符进行重载时,就必须区分前置和后置形式。C++根据参数的个数来区分前置和后置形式。如果按照通常的方法来重载 ++ 运算符(即作为成员函数重载时不带参数,或者作为非成员函数重载时带有一个参数),那么重载

二进制君 5832

从底层结构开始学习FPGA(7)----进位链CARRY4

进位链CARRY4在FPGA实现加减法运算时扮演了什么角色?

孤独的单刀 1万+

Java多线程编程最佳实践

线程是程序执行的最小单位,可以理解为程序内部独立运行的执行路径。如果把进程比作一个工厂,那么线程就是工厂里的工人,多个工人可以同时工作,大大提高整体效率。🚀提升性能:充分利用多核CPU,让程序真正并行执行⚡提高响应性:耗时操作在后台执行,主线程可以继续响应用户操作🔄资源共享:同一进程内的线程共享内存空间,通信成本低📈并发处理:同时处理多个任务,提升系统吞吐量想象一下,没有多线程的Web服务器只能一次处理一个用户请求,这在现代互联网应用中是不可接受的。

tym3125536957的博客 993

数学建模模型总结

这是本人在两年内准备参加数学建模竞赛搜集到的模型资料,已经经过了本人的筛选和整理,希望能够对准备参加数学建模竞赛的学弟学妹们提供一些帮助!

深入理解Java多线程与并发编程:从基础到实践

通过本文的介绍,希望读者能够掌握Java多线程的核心概念和最佳实践。在实际开发中,建议:优先考虑使用包中的高级工具谨慎使用低级别的同步机制充分测试多线程代码。

qq_57755194的博客 1106

大中型超市收银系统(可直接运行)

光步前台收银系统系统功能:商品销售、商品退货、挂单、收银员权限、会员销售、单品取消、整单取消、商品查询、脱机销售、脱机数据上传,基本资料下载,开钱箱、小票打印、收款结算,支持多币种付款方式(现金、储值卡、礼券、微信等),支持多种促销。运行环境:.net 4.0登陆信息用户名:1001 密码:123456内置商品信息,商品编码可输入00001000 - 00010000,测试效果相关功能键F5 结算 F9挂单 F11商品查询 F8退货 Insert单品取消 Del整单取消 F12开钱箱F2 会员 Ctrl+Z退出系统 Home 锁屏 相关源码待公开

WINCC7.3破解文件

WINCC7.3硬件够破解文件,有需要的下载!WINCC7.3硬件够破解文件,有需要的下载!

【Java多线程】10 Java 并发编程的最佳实践

通过将对象的状态设为不可更改,可以避免数据竞争和不一致的状态。使用线程池时,合理配置线程池的大小,可以有效提高并发性能。根据任务的性质和系统的资源状况来选择合适的线程池类型(如固定大小、可缓存等)。通过分析 CPU 和内存的使用情况、线程的活跃度等,找出性能瓶颈并进行优化。Java 提供了丰富的并发工具和类,尽量使用这些已有的并发类,而不是自己实现复杂的同步逻辑。长时间持有锁会降低并发性能,尽量将锁的持有时间缩短,避免在持有锁时执行耗时操作。在设计并发系统时,选择合适的锁策略非常重要。

A1924的博客 1276

霍尼韦尔SoftMaster使用说明

霍尼韦尔SoftMaster使用说明

Java多线程编程学习与实践

怎么样才算得上熟悉多线程编程?第一,明白进程和线程的基本概念第二,明白保护线程安全的基本方法有哪些第三,明白这些线程安全的方法,包括互斥锁,自旋锁,无锁编程的适用的业务场景是什么?从OS和硬件角度说说原理是怎么样的?开销在哪里?第四,能在现场借助cas操作,风险指针实现无锁的数据结构,比如无锁栈,无锁环形队列。无锁排序链表下面就来学习一下多线程的知识然后进行实践此文只能说是java多线程的一个入门...

xiao雷博客 1862
上一篇: 在Java程序中实现高精度打印-Java基础-Java-编程开发
下一篇: 全面理解Java中的String数据类型-Java基础-Java-编程开发
java169
博客等级 码龄18年 27粉丝 2568原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值