在线程异步的场合下,如何将线程信息传递到调用处(2)

简介: 在线程异步的场合下,如何将线程信息传递到调用处

修改主线程 写道

public static void main(String[] args) throws InterruptedException {


File input = new File("D:\\test\\demo01.html");

ReturnDigestThread thread = new ReturnDigestThread(input);

thread.start();


// 输出

StringBuffer result = new StringBuffer(input.toString());

result.append(": ");


// 进行轮询

int count = 0;

while (true) {

System.out.println(count++);

// 如果摘要为空,则进行获取

byte[] digest = thread.getDigest();

if (digest != null) {

for (int i = 0; i < digest.length; i++) {

result.append(digest[i] + " ");

}

System.out.println(result.toString());

// 然后退出循环

break;

}

}

}

结果 写道

...

659

660

661

662

663

664

665

666

667

D:\test\demo01.html: 84 56 116 -95 -96 -119 -123 -19 117 -125 22 48 53 13 -111 125 106 -66 44 69

子线程 写道

package network;


import java.io.File;

import java.io.FileInputStream;

import java.io.FileNotFoundException;

import java.io.IOException;

import java.security.DigestInputStream;

import java.security.MessageDigest;

import java.security.NoSuchAlgorithmException;


public class CallbackDigestThread extends Thread {

private File input;

public CallbackDigestThread(File input) {

this.input = input;

}


public void run() {

try {

FileInputStream in = new FileInputStream(this.input);

// 消息摘要

MessageDigest sha = MessageDigest.getInstance("SHA");

DigestInputStream din = new DigestInputStream(in, sha);


// 要完成消息摘要计算,先要调用此摘要输入流的一个 read 方法,之后在关联的消息摘要上调用一个 digest 方法。

while ((din.read()) != -1);

din.close();


// 回调主线程方法进行输出结果

CallbackDigestUserInterface.reciveDigest(sha.digest(), this.input.toString());

} catch (FileNotFoundException e) {

e.printStackTrace();

} catch (NoSuchAlgorithmException e) {

e.printStackTrace();

} catch (IOException e) {

e.printStackTrace();

}

}

}

主线程 写道

package network;


import java.io.File;


public class CallbackDigestUserInterface {


public static void main(String[] args) throws InterruptedException {

File input = new File("D:\\test\\demo01.html");

Thread thread = new CallbackDigestThread(input);

thread.start();

}


/**

* 通过提供该方法到子线程,子线程在得到digest后,回调该方法输出.

*

* @param digest

* @param name

*/

public static void reciveDigest(byte[] digest, String name) {

// 输出

StringBuffer result = new StringBuffer(name);

result.append(": ");


for (int i = 0; i < digest.length; i++) {

result.append(digest[i] + " ");

}

System.out.println(result.toString());

}


}

子线程 写道

package network;


import java.io.File;

import java.io.FileInputStream;

import java.io.FileNotFoundException;

import java.io.IOException;

import java.security.DigestInputStream;

import java.security.MessageDigest;

import java.security.NoSuchAlgorithmException;


public class InstanceCallbackDigestThread extends Thread {

private File input;

private InstanceCallbackDigestUserInterface callback;


// 通过构造方法,我们将实例对象传递过来

public InstanceCallbackDigestThread(File input, InstanceCallbackDigestUserInterface callback) {

this.input = input;

this.callback = callback;

}


public void run() {

try {

FileInputStream in = new FileInputStream(this.input);

// 消息摘要

MessageDigest sha = MessageDigest.getInstance("SHA");

DigestInputStream din = new DigestInputStream(in, sha);


// 要完成消息摘要计算,先要调用此摘要输入流的一个 read 方法,之后在关联的消息摘要上调用一个 digest 方法。

while ((din.read()) != -1);

din.close();


// 回调主线程方法进行输出结果

主类 写道

package network;


import java.io.File;


public class InstanceCallbackDigestUserInterface {


public static void main(String[] args) throws InterruptedException {

File input = new File("D:\\test\\demo01.html");

InstanceCallbackDigestUserInterface callback = new InstanceCallbackDigestUserInterface();


// 将实例对象传递到子线程中

Thread thread = new InstanceCallbackDigestThread(input, callback);

thread.start();

}


/**

* 通过提供该方法到子线程,子线程在得到digest后,回调该方法输出.

*

* @param digest

* @param name

*/

public void reciveDigest(byte[] digest, String name) {

// 输出

StringBuffer result = new StringBuffer(name);

result.append(": ");


for (int i = 0; i < digest.length; i++) {

result.append(digest[i] + " ");

}

System.out.println(result.toString());

}


}

 

} catch (FileNotFoundException e) {

e.printStackTrace();

} catch (NoSuchAlgorithmException e) {

e.printStackTrace();

} catch (IOException e) {

e.printStackTrace();

}

}

}

listener 写道

package network;


import java.io.File;

import java.io.FileInputStream;

import java.io.FileNotFoundException;

import java.io.IOException;

import java.security.DigestInputStream;

import java.security.MessageDigest;

import java.security.NoSuchAlgorithmException;


public class ListCallbackDigestRunnable implements Runnable {

private File input;

private DigestListener listener;


public ListCallbackDigestRunnable(File input) {

this.input = input;

}


private void sendDigest(byte[] digest) {

listener.digestCalculdated(digest);

}


public void run() {

try {

FileInputStream in = new FileInputStream(this.input);

// 消息摘要

MessageDigest sha = MessageDigest.getInstance("SHA");

DigestInputStream din = new DigestInputStream(in, sha);


// 要完成消息摘要计算,先要调用此摘要输入流的一个 read 方法,之后在关联的消息摘要上调用一个 digest 方法。

// read方法会因为文件的大小而阻塞

while ((din.read()) != -1)

;

din.close();


byte[] digest = sha.digest();


// 当前线程获取到当前文件的digest后,会通过listener将摘要信息通过主线程的接口方法进行输出.

this.sendDigest(digest);


} catch (FileNotFoundException e) {

e.printStackTrace();

} catch (NoSuchAlgorithmException e) {

e.printStackTrace();

} catch (IOException e) {

e.printStackTrace();

}

}


public DigestListener getListener() {

return listener;

}


public void setListener(DigestListener listener) {

this.listener = listener;

}

}

主程序 写道

package network;


import java.io.File;


public class ListCallbackDigestUserInterface implements DigestListener {


private File input;


public ListCallbackDigestUserInterface(File input) {

this.input = input;

}


/**

* 启动不同的线程,对消息摘要进行处理

*/

private void digestCalculated() {

ListCallbackDigestRunnable cb = new ListCallbackDigestRunnable(input);

// 为当前线程设置自己的listener

cb.setListener(this);


Thread t = new Thread(cb);

t.start();

}


public static void main(String[] args) throws InterruptedException {

// 进行三个文件的摘要信息输出

String[] filenames = { "D:\\test\\demo01 - 副本.html", "D:\\test\\demo01 - 副本 (2).html",

"D:\\test\\demo01.html" };

for (String filename : filenames) {

File input = new File(filename);

// 创建当前对象实例

ListCallbackDigestUserInterface d = new ListCallbackDigestUserInterface(input);

d.digestCalculated();

}

}


@Override

public void digestCalculdated(byte[] digest) {

// 输出

StringBuffer result = new StringBuffer(input.toString());

result.append(": ");


for (int i = 0; i < digest.length; i++) {

result.append(digest[i] + " ");

}

System.out.println(result.toString());

}


}

接口 写道

package network;


public interface DigestListener {


/**

* 对摘要进行处理.

*

* @param digest

*/

public void digestCalculdated(byte [] digest);

}

相关文章
|
4月前
|
数据采集 存储 JSON
Python爬取知乎评论:多线程与异步爬虫的性能优化
Python爬取知乎评论:多线程与异步爬虫的性能优化
|
4月前
|
数据采集 监控 调度
干货分享“用 多线程 爬取数据”:单线程 + 协程的效率反超 3 倍,这才是 Python 异步的正确打开方式
在 Python 爬虫中,多线程因 GIL 和切换开销效率低下,而协程通过用户态调度实现高并发,大幅提升爬取效率。本文详解协程原理、实战对比多线程性能,并提供最佳实践,助你掌握异步爬虫核心技术。
|
编解码 数据安全/隐私保护 计算机视觉
Opencv学习笔记(十):同步和异步(多线程)操作打开海康摄像头
如何使用OpenCV进行同步和异步操作来打开海康摄像头,并提供了相关的代码示例。
789 1
Opencv学习笔记(十):同步和异步(多线程)操作打开海康摄像头
|
6月前
|
Arthas 监控 Java
Arthas thread(查看当前JVM的线程堆栈信息)
Arthas thread(查看当前JVM的线程堆栈信息)
1134 10
|
9月前
|
缓存 安全 Java
面试中的难题:线程异步执行后如何共享数据?
本文通过一个面试故事,详细讲解了Java中线程内部开启异步操作后如何安全地共享数据。介绍了异步操作的基本概念及常见实现方式(如CompletableFuture、ExecutorService),并重点探讨了volatile关键字、CountDownLatch和CompletableFuture等工具在线程间数据共享中的应用,帮助读者理解线程安全和内存可见性问题。通过这些方法,可以有效解决多线程环境下的数据共享挑战,提升编程效率和代码健壮性。
322 6
|
10月前
|
监控 Java
java异步判断线程池所有任务是否执行完
通过上述步骤,您可以在Java中实现异步判断线程池所有任务是否执行完毕。这种方法使用了 `CompletionService`来监控任务的完成情况,并通过一个独立线程异步检查所有任务的执行状态。这种设计不仅简洁高效,还能确保在大量任务处理时程序的稳定性和可维护性。希望本文能为您的开发工作提供实用的指导和帮助。
385 17
|
缓存 Java
异步&线程池 线程池的七大参数 初始化线程的4种方式 【上篇】
这篇文章详细介绍了Java中线程的四种初始化方式,包括继承Thread类、实现Runnable接口、实现Callable接口与FutureTask结合使用,以及使用线程池。同时,还深入探讨了线程池的七大参数及其作用,解释了线程池的运行流程,并列举了四种常见的线程池类型。最后,阐述了在开发中使用线程池的原因,如降低资源消耗、提高响应速度和增强线程的可管理性。
异步&线程池 线程池的七大参数 初始化线程的4种方式 【上篇】
|
Java 数据库
异步&线程池 CompletableFuture 异步编排 实战应用 【终结篇】
这篇文章通过一个电商商品详情页的实战案例,展示了如何使用`CompletableFuture`进行异步编排,以解决在不同数据库表中查询商品信息的问题,并提供了详细的代码实现和遇到问题(如图片未显示)的解决方案。
异步&线程池 CompletableFuture 异步编排 实战应用 【终结篇】
|
设计模式 缓存 Java
谷粒商城笔记+踩坑(14)——异步和线程池
初始化线程的4种方式、线程池详解、异步编排 CompletableFuture
谷粒商城笔记+踩坑(14)——异步和线程池
|
安全 调度 C#
STA模型、同步上下文和多线程、异步调度
【10月更文挑战第19天】本文介绍了 STA 模型、同步上下文和多线程、异步调度的概念及其优缺点。STA 模型适用于单线程环境,确保资源访问的顺序性;同步上下文和多线程提高了程序的并发性和响应性,但增加了复杂性;异步调度提升了程序的响应性和资源利用率,但也带来了编程复杂性和错误处理的挑战。选择合适的模型需根据具体应用场景和需求进行权衡。
353 0

热门文章

最新文章