千家信息网

如何实现Java 5.0多线程编程

发表于:2024-11-12 作者:千家信息网编辑
千家信息网最后更新 2024年11月12日,这篇文章主要介绍了如何实现Java 5.0多线程编程,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。简介本文将实现一个网络服务器模型,一
千家信息网最后更新 2024年11月12日如何实现Java 5.0多线程编程

这篇文章主要介绍了如何实现Java 5.0多线程编程,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。

简介

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

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函数已经执行完毕,则取得返回值,如果还在执行,则等待其执行完毕。

感谢你能够认真阅读完这篇文章,希望小编分享的"如何实现Java 5.0多线程编程"这篇文章对大家有帮助,同时也希望大家多多支持,关注行业资讯频道,更多相关知识等着你来学习!

线程 服务 任务 方法 服务器 代码 函数 模型 端口 篇文章 监听 客户 客户端 接口 程序 类型 网络 编程 频繁 信息 数据库的安全要保护哪些东西 数据库安全各自的含义是什么 生产安全数据库录入 数据库的安全性及管理 数据库安全策略包含哪些 海淀数据库安全审计系统 建立农村房屋安全信息数据库 易用的数据库客户端支持安全管理 连接数据库失败ssl安全错误 数据库的锁怎样保障安全 软件开发程序代码图片 软件开发红米笔记本可以用吗 惠普服务器ip地址配置 服务器启动程序是什么 鄞州直销软件开发教程 猫和老鼠游戏服务器卡屏怎么办 tp 多数据库 hmcl单人开不开总连到服务器 橙绩网络技术有限公司 电脑显示dhcp服务器未开启 数据库开发是做成软件 网络技术法ppt 自己买个服务器上网违法吗 数据库多端口读写 网络安全管理和电子商务师哪个好 平度ios软件开发企业 可爱小说软件开发 个人征信信息数据库数据更新频率 搭建企业内部存储服务器并分级 自然界存在最多的服务器 网络技术服务业行业现状 鄞州直销软件开发教程 软件开发设计思路与原则 漯河做app的软件开发 评论嵌套数据库怎么设计 网络安全协调指挥系统 环境和数据库演示是什么意思 海康服务器电源灯绿灯一闪一闪 如何快速创建房产网站数据库 金山区会计软件开发五星服务
0