Thread - Thread Execution

本文深入探讨了线程与线程池的实现方式,包括使用Thread和ThreadPoolExecutor,以及如何通过Future获取运行结果。通过示例展示了如何在不同场景下选择合适的运行体(Runnable或Callable),并利用FutureTask实现异步计算。同时,介绍了如何在ThreadPoolExecutor中提交任务以及如何使用Future来获取结果,强调了线程池在减少创建和销毁线程方面的作用。

线程运行工具也有两种方法实现:

1、Thread

2、ThreadPool

      - Executors.xxx.submit: 运行器  (submit, return Future)

      - ThreadPoolExecutor.execute: 线程池运行器  (execute, void)

主要区别:线程池循环使用线程池中的线程,减少创建和销毁线程。

可以用Future接收运行结果


运行体主要有两种方法实现:

1、Runnable(), run()

2、Callable(), call()

主要区别:Run 没有返回值,Call有返回值。

可以把运行体封装成FutureTask。


一、准备线程

1、Thread

Thread t = new Thread([Runnable | Callable]);

2、Thread Pool Executor

ExecutorService executor = Executors.newFixedThreadPool(n);  // n threads; newSingleThreadExecutor(), newScheduledThreadPool(), ...


二、运行体

1、Run

new Runnable() {
  public void run() {...}
}

2、Call

new Callable<String>() {
  public String call() throws Exception {...; return ...}  // e.g. return String type
}

3、FutureTask

Callable<String> task = ...;  // or Runnable
FutureTask<String> ft = new FutureTask<String>(task);  // e.g.String

三、运行

1、Thread

t.start();

2、Thread Pool Executor

executor.submit([Callable | Runnable])

3、Future

Future<String> future = executor.submit(...)  // similar to thread.start


四、Sample

public class Thread01_future extends Thread {

	public static void main(String[] args) {
		// Future: 异步计算结果

		// Thread.start: 运行器
		// Executors.xxx.submit: 运行器
		// ThreadPoolExecutor.execute: 线程池运行器
		// (execute, void) (submit, return Future)

		// FutureTask: 异步计算任务
		// Runnable(), run(): 运行任务(运行类、运行方法,void)
		// Callable(), call(): 运行任务(运行类、运行方法,return)

		// test01();
		// test02();
		test03();

	}

	// Future: 异步计算结果
	// Executors.xxx.submit: 运行器
	// Runnable(), run(): 运行任务(运行类、运行方法,void)
	// Callable(), call(): 运行任务(运行类、运行方法,return)
	public static void test01() {
		// 创建一个执行任务的服务
		ExecutorService executor = Executors.newFixedThreadPool(3);

		try {
			// 1. A Runnable, however, does not return a result and cannot throw
			// checked exception.
			System.out.println("~~~1");
			Future<?> runnable1 = executor.submit(new Runnable() {
				@Override
				public void run() {
					System.out.println("runnable1 running.");
				}
			});
			System.out.println("Runnable1:" + runnable1.get());

			// 2. Callable
			System.out.println("~~~2");
			Future<String> future1 = executor.submit(new Callable<String>() {
				@Override
				public String call() throws Exception {
					return "result=task1";
				}
			});
			System.out.println("task1: " + future1.get());

			// 3. 对Callable调用cancel可以对对该任务进行中断
			System.out.println("~~~3");
			Future<String> future2 = executor.submit(new Callable<String>() {
				@Override
				public String call() throws Exception {
					try {
						while (true) {
							System.out.println("task2 running.");
							Thread.sleep(50);
						}
					} catch (InterruptedException e) {
						System.out.println("Interrupted task2.");
					}
					return "task2=false";
				}
			});
			// 等待5秒后,再停止第二个任务。因为第二个任务进行的是无限循环
			Thread.sleep(101);
			System.out.println("task2 cancel: " + future2.cancel(true));

			// 4.用Callable时抛出异常则Future什么也取不到了
			// 获取第三个任务的输出,因为执行第三个任务会引起异常
			// 所以下面的语句将引起异常的抛出
			System.out.println("~~~4");
			Future<String> future3 = executor.submit(new Callable<String>() {
				@Override
				public String call() throws Exception {
					throw new Exception("task3 throw exception!");
				}
			});
			// Thread.sleep(133);
			System.out.println("task3: " + future3.get());


		} catch (InterruptedException e) {
			e.printStackTrace();
		} catch (ExecutionException e) {
			e.printStackTrace();
		}

		// 停止任务执行服务
		executor.shutdownNow();
	}

	// FutureTask: 异步计算任务
	// Thread, Executors.xxx.submit: 运行器
	public static void test02() {
		Callable<String> task = new Callable<String>() {
			@Override
			public String call() {
				System.out.println("Sleep start.");
				try {
					Thread.sleep(1000 * 3);
				} catch (InterruptedException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
				System.out.println("Sleep end.");
				return "time=" + System.currentTimeMillis();
			}
		};

		// 直接使用Thread的方式执行
		FutureTask<String> ft = new FutureTask<String>(task);
		Thread t = new Thread(ft);
		t.start();
		try {
			System.out.println("waiting execute result");
			System.out.println("result = " + ft.get());
		} catch (InterruptedException e) {
			e.printStackTrace();
		} catch (ExecutionException e) {
			e.printStackTrace();
		}

		// 使用Executors来执行
		System.out.println("=========");
		FutureTask<String> ft2 = new FutureTask<String>(task);
		Executors.newSingleThreadExecutor().submit(ft2);
		try {
			System.out.println("waiting execute result");
			System.out.println("result = " + ft2.get());
		} catch (InterruptedException e) {
			e.printStackTrace();
		} catch (ExecutionException e) {
			e.printStackTrace();
		}
	}

	// ThreadPoolExecutor.execute: 线程池运行器
	public static void test03() {
		int produceTaskMaxNumber = 4;
		// 构造一个线程池
		ThreadPoolExecutor threadPool = new ThreadPoolExecutor(2, 4, 3,
				TimeUnit.SECONDS, new ArrayBlockingQueue<Runnable>(10),
				new ThreadPoolExecutor.DiscardOldestPolicy());

		ArrayList<FutureTask<String>> tasks = new ArrayList<FutureTask<String>>();
		for (int i = 1; i <= produceTaskMaxNumber; i++) {
			try {
				// 产生一个任务,并将其加入到线程池
				Callable<String> task = new Callable<String>() {
					@Override
					public String call() {
						String task = "task@ ";
						System.out.println("put " + task);
						return task;
					}
				};
				FutureTask<String> futureTask = new FutureTask<String>(
						task);
				threadPool.execute(futureTask);
				tasks.add(futureTask);

			} catch (Exception e) {
				e.printStackTrace();
			}
		}

		for (FutureTask<String> futureTask : tasks) {
			// 1秒内获得结果 (1st arg: the maximum time to wait, 2nd arg: the time
			// unit of the timeout argument)
			String str = null;
			try {
				str = "stop " + futureTask.get(1, TimeUnit.SECONDS);
			} catch (InterruptedException e) {
				e.printStackTrace();
			} catch (ExecutionException e) {
				e.printStackTrace();
			} catch (TimeoutException e) {
				e.printStackTrace();
			}
			System.out.println(str);
		}
	}
}




### RT-Thread CanFestival CANopen Protocol Stack Integration and Usage In the context of integrating a CANopen protocol stack into an embedded system using RT-Thread, one viable option is utilizing CanFestival[^1]. CanFestion provides comprehensive support for implementing CANopen nodes within various operating systems including real-Thread. #### Installation Process To integrate CanFestival with RT-Thread, developers should first ensure that both environments are properly set up on their development machine. The installation process involves downloading or cloning the CanFestival repository from its official source control platform. Afterward, configuring it to work alongside RT-Thread requires adjustments in project settings such as adding necessary include paths and linking against required libraries provided by either environment. ```bash git clone https://github.com/CANfestival/canfestival.git cd canfestival make rt-thread ``` This command sequence assumes that Git has been installed along with any prerequisites needed for building projects targeting RT-Thread platforms. #### Configuration Adjustments Once successfully integrated at build time through configuration files (e.g., `rtconfig.h`), specific configurations related to hardware abstraction layers must be addressed so that communication between physical CAN controllers and software components occurs seamlessly without conflicts arising due to differences in timing requirements imposed by different parts involved during runtime operations. For instance, setting up proper interrupt priorities ensures timely processing while avoiding potential issues caused by resource contention among multiple tasks running concurrently under tight scheduling constraints typical found within hard-realtime applications built upon microcontroller units (MCUs). #### Example Code Snippet Demonstrating Basic Initialization Steps Below demonstrates how initialization might look when incorporating CanFestival's API calls directly inside application code written specifically for use cases involving RT-Thread: ```c #include "canfestival.h" // Other includes... void init_can_open(void){ CO_ReturnError_t ret; /* Initialize CAN interface */ if ((ret = CO_CANinit(CO_CANmodule, 0)) != CO_ERROR_NO) { // Handle error... } /* Start CANopen Node */ if((ret = CO_CANsetConfigurationMode(CO_CANmodule))!=CO_ERROR_NO || (ret = CO_init(&NMT,&HeartbeatProducer,CANnodeId,CO_CANmodule)!=CO_ERROR_NO)){ // Error handling here. } } ``` The above C snippet initializes key aspects of working with CANopen via CanFestival APIs tailored towards being compatible with what RT-Thread offers regarding task management and inter-process communications mechanisms which facilitate efficient execution flow throughout entire programs designed around these technologies combined together effectively creating robust solutions capable enough even for mission-critical scenarios where reliability matters most. --related questions-- 1. What challenges may arise when porting CanFestival onto non-standard architectures supported by RT-Thread? 2. How does CanFestival handle errors internally compared to other similar stacks available today? 3. Are there any known limitations concerning performance metrics associated with this particular combination setup described earlier? 4. In terms of security features offered out-of-the-box, how well-equipped is CanFestival relative to alternatives present across market offerings catering especially toward industrial automation sectors relying heavily upon secure data exchange protocols over fieldbuses like those based off CAN technology standards? 5. Could you provide examples illustrating best practices recommended when developing complex multi-node networks leveraging capabilities exposed through integration points established between RT-Thread OS layer abstractions versus lower-level driver implementations interfacing directly with underlying hardware resources managing actual bit transmissions occurring physically over wires connecting all devices participating actively within same network topology instances deployed practically anywhere ranging widely indoors/outdoors environments alike depending largely upon intended application domain specifics driving design choices made upfront before implementation phases commence officially post-planning stages completion milestones reached satisfactorily according stakeholders' expectations outlined clearly documented requirement specifications agreed mutually amongst parties involved collaboratively throughout entire lifecycle span covering conception until decommission eventually?
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值