Java多线程实现
- 格式:doc
- 大小:63.00 KB
- 文档页数:12
java多线程实际应用案例Java多线程是一种并发编程的方式,可以使程序同时执行多个任务,提高程序的执行效率和响应速度。
下面列举了十个Java多线程实际应用案例。
1. 电商网站订单处理:在一个电商网站中,订单的处理是一个非常繁琐且耗时的工作,可以使用多线程实现订单的并发处理,提高订单处理的效率。
2. 聊天软件消息发送:在聊天软件中,用户发送消息是一个频繁的操作,可以使用多线程实现消息的并发发送,提高用户体验。
3. 数据库读写操作:在数据库的读写操作中,读操作可以使用多线程并发执行,提高数据的读取速度;写操作可以使用多线程并发执行,提高数据的写入速度。
4. 图像处理:在图像处理中,可以使用多线程实现图像的并行处理,提高图像处理的速度。
5. 视频编解码:在视频编解码中,可以使用多线程实现视频的并行编解码,提高视频的处理速度。
6. 网络爬虫:在网络爬虫中,可以使用多线程实现并发的爬取网页数据,提高爬虫的效率。
7. 游戏开发:在游戏开发中,可以使用多线程实现游戏的并行处理,提高游戏的运行速度和响应速度。
8. 大数据处理:在大数据处理中,可以使用多线程实现并发的数据处理,提高大数据处理的效率。
9. 并发服务器:在服务器开发中,可以使用多线程实现并发的请求处理,提高服务器的并发能力。
10. 并发任务调度:在任务调度中,可以使用多线程实现并发的任务执行,提高任务的执行效率。
在实际应用中,多线程不仅可以提高程序的执行效率和响应速度,还可以充分利用多核处理器的优势,实现并行计算和并发处理。
然而,多线程编程也面临着诸多挑战,如线程安全、死锁、资源竞争等问题,需要设计合理的线程同步和互斥机制,确保程序的正确性和稳定性。
因此,在使用多线程编程时,需要仔细考虑线程间的依赖关系和数据共享问题,合理规划线程的数量和调度策略,确保多线程程序的正确性和性能。
java多线程编程实验总结与体会[Java多线程编程实验总结与体会]本次实验锻炼了我的Java多线程编程能力,让我更深入地了解了多线程编程的实现原理和技巧,同时也让我意识到在多线程环境下需要考虑的问题和注意事项。
下面我将结合具体实验内容,分享我在实践中的体会和思考。
1. 实验环境搭建在进行本次实验之前,我首先进行了实验环境的搭建。
我选择了Java SE Development Kit 8和Eclipse作为开发工具,同时也安装了JDK8的API 文档作为参考资料。
在搭建环境的过程中,我认识到Java的生态系统非常强大,附带的工具和资源也非常充足,这为我们开发和调试带来了很大的便利。
2. 多线程原理在研究多线程编程之前,我们需要对Java语言中的线程概念有一个清晰的认识。
线程是指操作系统能够进行运算调度的最小单位,是执行线程代码的路径。
在Java中,线程是一种轻量级的进程,可以同时运行多个线程。
每个线程都有自己的堆栈和局部变量,线程之间可以共享全局变量。
Java的多线程编程是通过Thread类和Runnable接口来实现的。
在实践中,我发现多线程编程最基本的原理是线程的并发执行。
多个线程可以在同一时间内执行不同的代码,提高CPU利用率,加快程序运行速度。
但是,在多线程并发执行的过程中,我们需要注意线程之间的同步问题,避免出现数据竞争和并发安全等问题。
3. 多线程的实现在Java中,我们可以通过继承Thread类或者实现Runnable接口来创建线程。
对于简单的线程,我们可以采用继承Thread类的方式来实现。
例如,在实验一中,我们在Main线程内创建了两个子线程,分别用来执行奇数和偶数的累加操作。
我们可以分别定义两个类OddThread和EvenThread继承Thread类,分别实现run()方法,用来执行具体的奇数和偶数累加操作。
然后在Main线程内创建OddThread和EvenThread 对象,并调用start()方法来启动两个线程,并等待两个线程完成操作。
java多线程累加计数的实现⽅法题⽬给定count=0;让5个线程并发累加到1000;思路创建⼀个类MyRunnable,实现Runnable(继承Thread类也可)定义⼀个公共变量count(初始值为0),5个线程都可以访问到;创建5个线程并发递增count到1000;注意这块注意Thread和Runnable类的区别,Thread类是线程类,可以直接new Thread().start运⾏。
⽽Runnable类是任务类,需要⼀个线程来承载任务,通过new Thread(new Runnable()).start()来运⾏任务。
⽅法⽅法⼀将count公共变量放到测试类Test的类成员变量⾥,将MyRunnable类作为Test类的内部类,在Test类的main⽅法⾥创建5个线程,实现累加。
代码public class Test {//公共变量int count=0;public static void main(String[] args){//new⼀个实现Runnable的类Test test=new Test();//创建5个任务MyRunnable myRunnable1=test.new MyRunnable();MyRunnable myRunnable2=test.new MyRunnable();MyRunnable myRunnable3=test.new MyRunnable();MyRunnable myRunnable4=test.new MyRunnable();MyRunnable myRunnable5=test.new MyRunnable();//创建5个线程new Thread(myRunnable1).start();new Thread(myRunnable2).start();new Thread(myRunnable3).start();new Thread(myRunnable4).start();new Thread(myRunnable5).start();}//创建⼀个实现Runnable的类class MyRunnable implements Runnable{public void run() {while(true){//锁住的是整个MyRunnable类synchronized(MyRunnable.class){if(count>=1000){break;}System.out.println(Thread.currentThread().getName()+":count:"+(++count));//测试时,线程更容易切换Thread.yield();}}}}}⽅法⼆以上代码没有问题,成功实现5个线程累加count到1000,接下来我们将上边代码稍作修改。
java多线程程序设计实验总结一、实验目的本次实验旨在通过编写Java多线程程序,掌握多线程编程的基本概念和技能,理解多线程程序的运行原理,提高对Java语言的熟练度。
二、实验内容本次实验分为三个部分:创建线程、线程同步和死锁。
2.1 创建线程创建线程有两种方式:继承Thread类和实现Runnable接口。
继承Thread类需要重写run方法,在run方法中编写线程执行的代码;实现Runnable接口需要实现run方法,并将其作为参数传入Thread类的构造函数中。
在创建多个线程时,可以使用同一个Runnable对象或者不同的Runnable对象。
2.2 线程同步当多个线程同时访问共享资源时,可能会出现数据不一致等问题。
为了避免这种情况,需要使用同步机制来保证各个线程之间的协调运行。
常见的同步机制包括synchronized关键字和Lock接口。
synchronized关键字可以用来修饰方法或代码块,在执行该方法或代码块时,其他所有试图访问该方法或代码块的线程都必须等待当前执行完成后才能继续执行。
Lock接口提供了更加灵活和高级的锁机制,可以支持更多种类型的锁,如读写锁、可重入锁等。
2.3 死锁死锁是指两个或多个线程在互相等待对方释放资源的情况下,都无法继续执行的现象。
死锁的发生通常由于程序设计不当或者资源分配不合理所导致。
为避免死锁的发生,可以采取以下措施:避免嵌套锁、按照固定顺序获取锁、避免长时间占用资源等。
三、实验过程本次实验我编写了多个Java多线程程序,包括创建线程、线程同步和死锁。
其中,创建线程部分我使用了继承Thread类和实现Runnable 接口两种方式来创建线程,并测试了多个线程之间的并行执行情况;在线程同步部分,我使用synchronized关键字和Lock接口来保证共享资源的访问安全,并测试了多个线程同时访问共享资源时是否会出现数据不一致等问题;在死锁部分,我编写了一个简单的死锁程序,并通过调整程序代码来避免死锁的发生。
java 实现callable多线程回调的原理在Java中,实现Callable多线程回调的原理是通过使用Callable接口和Future 接口的组合来实现的。
Callable接口是一个泛型接口,它定义了一个call()方法,该方法可以在多线程环境下执行任务并返回结果。
与Runnable接口不同的是,call()方法可以返回一个结果对象。
为了能够获取Callable任务的返回结果,可以使用Future接口。
Future接口代表了异步计算的结果,它提供了一些方法来检查任务是否完成、取消任务的执行和获取任务的返回结果。
具体的实现步骤如下:1. 创建一个实现Callable接口的类,该类的call()方法中编写需要并发执行的任务逻辑,并返回一个结果对象。
2. 在主线程中使用ExecutorService创建线程池并提交Callable任务,这样可以异步执行任务。
例如:```ExecutorService executorService = Executors.newFixedThreadPool(1);Future<String> future = executorService.submit(new MyCallable());```3. 使用Future对象的get()方法来获取Callable任务的返回结果。
该方法会阻塞主线程,直到任务完成并返回结果。
例如:```try {String result = future.get();// 处理任务返回结果} catch (InterruptedException | ExecutionException e) {e.printStackTrace();}```通过以上步骤,我们可以在Java中实现Callable多线程回调的原理。
这种方式可以提高并发处理任务的效率,同时利用Future对象可以获取并处理任务的返回结果。
java多线程的实验报告Java多线程的实验报告一、引言多线程是计算机科学中一个重要的概念,它可以提高程序的并发性和效率。
Java作为一种广泛应用的编程语言,也提供了丰富的多线程支持。
本实验旨在通过编写多线程程序,探索Java多线程的特性和使用方法。
二、实验目的1. 理解多线程的概念和原理;2. 掌握Java多线程的基本使用方法;3. 分析多线程程序的执行过程和效果。
三、实验过程1. 创建多线程在Java中,可以通过继承Thread类或实现Runnable接口来创建多线程。
本实验选择实现Runnable接口的方式。
首先,定义一个实现了Runnable接口的类MyThread,重写run()方法,在该方法中编写线程的具体逻辑。
2. 启动多线程在主线程中,创建MyThread对象,并通过Thread类的构造函数将其作为参数传入。
然后,调用Thread类的start()方法启动线程。
3. 线程同步在多线程程序中,为了避免线程之间的数据竞争和冲突,需要进行线程同步。
Java提供了synchronized关键字和Lock接口来实现线程同步。
本实验使用synchronized关键字来保证线程的安全性。
4. 线程通信多线程之间的通信可以通过共享变量、wait()和notify()方法来实现。
本实验通过共享变量来实现线程通信,其中一个线程负责生产数据,另一个线程负责消费数据。
5. 线程池Java提供了Executor框架来管理线程池。
通过使用线程池,可以减少线程的创建和销毁开销,提高程序的性能。
本实验使用Executor框架来管理线程池,并设置合适的线程数量。
四、实验结果通过以上实验过程,成功实现了多线程程序,并观察到了以下结果:1. 多线程的执行顺序是不确定的,不同线程的执行顺序可能不同;2. 多线程程序可以提高程序的并发性和效率;3. 线程同步能够保证多线程程序的安全性;4. 线程通信可以实现多线程之间的数据交换和协作;5. 使用线程池可以提高程序的性能。
多线程的三种实现方式多线程是指程序中同时运行多个线程的机制,可以提高程序的并发性和效率。
在实际的开发过程中,有三种常见的多线程实现方式:继承Thread类、实现Runnable接口和使用线程池。
一、继承Thread类继承Thread类是实现多线程的一种简单方式。
具体步骤如下:1. 定义一个继承自Thread的子类,重写run方法,该方法在新线程中执行。
2. 在主线程中创建子线程的实例,并调用其start方法启动线程。
下面是一个简单的示例代码:```class MyThread extends Threadpublic void rufor (int i = 0; i < 10; i++)System.out.println("Thread-1: " + i);}}public class Mainpublic static void main(String[] args)MyThread thread = new MyThread(;thread.start(;for (int i = 0; i < 10; i++)System.out.println("Main Thread: " + i);}}```在上述代码中,MyThread继承自Thread类,并重写了run方法,在run方法中打印10次当前线程的名称与循环变量的值。
在主线程中创建MyThread的实例,并调用其start方法启动子线程,然后主线程中也打印10次循环变量的值。
运行以上代码,可以看到两个线程并发执行,输出结果交替显示。
二、实现Runnable接口实现Runnable接口是另一种实现多线程的方式,相比继承Thread类,这种方式可以更好地解决Java单继承的限制,增强程序的扩展性和复用性。
具体步骤如下:1. 定义一个类实现Runnable接口,重写run方法,该方法在新线程中执行。
JAVA开发中的多线程编程技术Java作为一种广泛应用于企业级应用以及各种工业自动化系统的编程语言,其对于处理多线程并发的问题起到了巨大的作用。
在Java开发过程中,我们经常会遇到需要多线程并发处理的情况,比如高并发的Web服务、大数据处理、图像处理等等。
如何正确合理的使用Java多线程技术是一个非常重要的问题。
本文将详细讲解Java开发中的多线程编程技术。
1.了解Java线程模型Java语言具有完善的线程模型,并提供了Thread类以及Runnable接口,方便程序员进行多线程编程。
在进行Java多线程编程的过程中,必须先理解Java的线程模型,包括线程的创建、使用、同步、互斥、线程间通信等。
同时,也要掌握Java虚拟机的内存结构以及线程调度器的工作原理,这些对多线程编程至关重要。
2.使用synchronized实现线程同步在多线程编程中,需要涉及到许多复杂的操作,如多个线程同时对同一共享数据进行读写操作会造成数据不一致等问题。
这时需要使用synchronized关键字来进行同步。
通过对象锁的机制,保证每个时间段只有一个线程能够访问同一个对象的同步代码块。
当线程进入一个对象的同步块时,将获得该对象的锁,只有等线程退出同步块或发生异常时才会释放锁,其他线程才能进入同步块。
通过synchronized关键字的同步机制能控制线程的读写顺序,使多个线程协同工作,防止数据不一致的问题。
3.使用volatile变量实现线程间通信在多线程编程中,需要进行线程间的通信。
在Java语言中,volatile变量可以用来实现线程间的通信。
当一个变量被声明为volatile变量后,所有线程对这个变量的读写操作都会直接在内存中进行,而不会使用线程的缓存中间值。
这样可以避免数据缓存的不一致,并保证在不同线程中读写的顺序是一致的,从而实现了线程之间的通信。
4.掌握并发包中的工具类Java并发包提供了许多实用的工具类,方便程序员在多线程编程中使用。
Java五种⽅式实现多线程循环打印问题⽬录wait-notifyjoin⽅式ReentrantLockReentrantLock+ConditionSemaphore三个线程T1、T2、T3轮流打印ABC,打印n次,如ABCABCABCABC…N个线程循环打印1-100…wait-notify循环打印问题可以通过设置⽬标值,每个线程想打印⽬标值,如果拿到锁后这次轮到的数不是它想要的就进⼊wait class Wait_Notify_ABC {private int num;private static final Object Lock = new Object();private void print_ABC(int target) {synchronized (Lock) {//循环打印for (int i = 0; i < 10; i++) {while (num % 3 != target) {try {Lock.wait();} catch (InterruptedException e) {e.printStackTrace();}}num++;System.out.print(Thread.currentThread().getName());Lock.notifyAll();}}}public static void main(String[] args) {Wait_Notify_ABC wait_notify_abc = new Wait_Notify_ABC();new Thread(() -> {wait_notify_abc.print_ABC(0);}, "A").start();new Thread(() -> {wait_notify_abc.print_ABC(1);}, "B").start();new Thread(() -> {wait_notify_abc.print_ABC(2);}, "C").start();}}打印1-100问题可以理解为有个全局计数器记录当前打印到了哪个数,其它就和循环打印ABC问题相同。
java中实现多线程的方法Java是一种非常强大的编程语言,它支持多线程,这是Java的一个重要特性。
多线程允许同时执行多个任务,从而大大提高了应用程序的效率和性能。
在Java中实现多线程的方法有很多种,下面我们将一步步地阐述这些方法。
第一种方法是继承Thread类。
我们可以在Java中创建一个继承Thread类的子类,并在子类中实现run()方法。
在run()方法中编写多线程代码。
以下是示例代码:```class MyThread extends Thread {public void run() {//多线程代码}}```在上述代码中,我们创建了一个名为MyThread的子类,并重写了Thread类的run()方法。
第二种方法是实现Runnable接口。
这种方法需要创建一个实现Runnable接口的类,然后实例化一个Thread对象并将实现Runnable 接口的类作为参数传递给Thread对象。
以下是示例代码:class MyRunnable implements Runnable {public void run() {//多线程代码}}public class Main {public static void main(String[] args) {MyRunnable obj = new MyRunnable();Thread thread = new Thread(obj);thread.start();}}```在上述代码中,我们创建了一个名为MyRunnable的类,并实现了Runnable接口。
我们在主类中创建了一个MyRunnable对象,并通过传递该对象作为参数创建了一个Thread对象。
最后启动线程。
第三种方法是使用匿名内部类。
这种方法可以减少代码的数量。
以下是示例代码:```public class Main {public static void main(String[] args) {new Thread(new Runnable() {public void run() {//多线程代码}}).start();}```在上述代码中,我们使用匿名内部类创建了一个Runnable对象并启动了一个线程。
下面要和大家分享的是Java多线程的实践,其实Java增加了新的类库并发集java.util.concurrent,该类库为并发程序提供了丰富的API多线程编程在Java 5中更加容易,灵活。
本文通过一个网络服务器模型,来实践Java5的多线程编程,该模型中使用了Java5中的线程池,阻塞队列,可重入锁等,还实践了Callable,Future 等接口,并使用了Java 的另外一个新特性泛型。
简介本文将实现一个网络服务器模型,一旦有客户端连接到该服务器,则启动一个新线程为该连接服务,服务内容为往客户端输送一些字符信息。
一个典型的网络服务器模型如下: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对象来初始化监听端口。
Java代码private static final int PORT = 19527;serverListenSocket = new ServerSocket(PORT);serverListenSocket.setReuseAddress(true);服务新连接当有新连接建立时,accept返回时,将服务任务提交给线程池执行。
Java代码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保证代码线程安全。
下面是具体代码:Java代码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();}}服务线程在开始给客户端打印一个欢迎信息,Java代码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方法来获取结果,如果这时候该方法已经执行完毕,则无需等待即可获得结果,如果还在执行,则等待到运行完毕。
Java代码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代码package com.andrew;import java.io.DataOutputStream;import java.io.IOException;import java.io.Serializable;import .ServerSocket;import .Socket;import java.util.concurrent.ArrayBlockingQueue;import java.util.concurrent.BlockingQueue;import java.util.concurrent.Callable;import java.util.concurrent.ExecutionException;import java.util.concurrent.ExecutorService;import java.util.concurrent.Executors;import java.util.concurrent.Future;import java.util.concurrent.RejectedExecutionHandler; import java.util.concurrent.ThreadPoolExecutor;import java.util.concurrent.TimeUnit;import java.util.concurrent.locks.ReentrantLock;public class Server {private static int produceTaskSleepTime = 100; private static int consumeTaskSleepTime = 1200; private static int produceTaskMaxNumber = 100;private static final int CORE_POOL_SIZE = 2;private static final int MAX_POOL_SIZE = 100;private static final int KEEPALIVE_TIME = 3;private static final int QUEUE_CAPACITY = (CORE_POOL_SIZE + MAX_POOL_SIZE) / 2; private static final TimeUnit TIME_UNIT = TimeUnit.SECONDS;private static final String HOST = "127.0.0.1";private static final int PORT = 19527;private BlockingQueue workQueue = new ArrayBlockingQueue(QUEUE_CAPACITY);//private ThreadPoolExecutor serverThreadPool = null;private ExecutorService pool = null;private RejectedExecutionHandler rejectedExecutionHandler = newThreadPoolExecutor.DiscardOldestPolicy();private ServerSocket serverListenSocket = null;private int times = 5;public void start() {// You can also init thread pool in this way./*serverThreadPool = new ThreadPoolExecutor(CORE_POOL_SIZE,MAX_POOL_SIZE, KEEPALIVE_TIME, TIME_UNIT, workQueue,rejectedExecutionHandler);*/pool = Executors.newFixedThreadPool(10);try {serverListenSocket = new ServerSocket(PORT);serverListenSocket.setReuseAddress(true);System.out.println("I'm listening");while (times-- > 0) {Socket socket = serverListenSocket.accept(); String welcomeString = "hello";//serverThreadPool.execute(new ServiceThread(socket, welcomeString)); pool.execute(new ServiceThread(socket));}} catch (IOException e) {// TODO Auto-generated catch blocke.printStackTrace();}cleanup();}public void cleanup() {if (null != serverListenSocket) {try {serverListenSocket.close();} catch (IOException e) {// TODO Auto-generated catch blocke.printStackTrace();}}//serverThreadPool.shutdown();pool.shutdown();}public static void main(String args[]) {Server server = new Server();server.start();}}class ServiceThread implements Runnable, Serializable {private static final long serialVersionUID = 0;private Socket connectedSocket = null;private String helloString = null;private static int count = 0;private static ReentrantLock lock = new ReentrantLock(); ServiceThread(Socket socket) {connectedSocket = socket;}public void run() {increaseCount();int curCount = getCount();helloString = "hello, id = " + curCount + "\r\n";ExecutorService executor = Executors.newSingleThreadExecutor();Future future = executor.submit(new TimeConsumingTask());DataOutputStream dos = null;try {dos = new DataOutputStream(connectedSocket.getOutputStream());dos.write(helloString.getBytes());try {dos.write("let's do soemthing other.\r\n".getBytes()); String result = future.get();dos.write(result.getBytes());} catch (InterruptedException e) {e.printStackTrace();} catch (ExecutionException e) {e.printStackTrace();}} catch (IOException e) {// TODO Auto-generated catch blocke.printStackTrace();} finally {if (null != connectedSocket) {try {connectedSocket.close();} catch (IOException e) {// TODO Auto-generated catch block e.printStackTrace();}}if (null != dos) {try {dos.close();} catch (IOException e) {// TODO Auto-generated catch block e.printStackTrace();}}executor.shutdown();}}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();}}}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";}}。