实现带参数的多线程的方式
- 格式:doc
- 大小:37.00 KB
- 文档页数:2
多线程超级列表框现行选中项传参1. 引言多线程是指在一个程序中同时执行多个线程的技术,它可以提高程序的并发性和响应性。
超级列表框是一种强大的控件,可以用于显示和管理大量数据。
在某些情况下,我们可能需要在多线程环境下使用超级列表框,并且需要将当前选中项作为参数传递给其他线程进行处理。
本文将介绍如何在多线程环境下实现超级列表框的选中项传参功能。
2. 多线程基础在开始讨论多线程超级列表框的选中项传参之前,我们首先需要了解多线程的基本知识。
在Python中,可以使用threading模块来创建和管理线程。
以下是一个简单的多线程示例:import threadingdef print_number():for i in range(1, 6):print(i)def print_letter():for i in range(ord('A'), ord('F')):print(chr(i))if __name__ == '__main__':t1 = threading.Thread(target=print_number)t2 = threading.Thread(target=print_letter)t1.start()t2.start()在上面的示例中,我们创建了两个线程,一个打印数字1到5,另一个打印字母A到E。
通过调用start()方法启动线程,线程会并发执行,输出结果可能是交替的。
3. 超级列表框介绍超级列表框(Super Listbox)是一种功能强大的列表框控件,它可以显示大量数据并提供丰富的交互功能,如滚动、排序、过滤等。
在Python中,可以使用tkinter模块创建超级列表框。
以下是一个简单的超级列表框示例:import tkinter as tkfrom tkinter import ttkdef on_select(event):selected_item = event.widget.get(event.widget.curselection())print(f"Selected item: {selected_item}")root = ()listbox = tk.Listbox(root)listbox.pack()listbox.bind("<<ListboxSelect>>", on_select)for i in range(1, 11):listbox.insert(tk.END, f"Item {i}")root.mainloop()在上面的示例中,我们创建了一个包含10个项目的超级列表框,并通过绑定<<ListboxSelect>>事件来获取当前选中的项目。
c++多线程实现方法C++是一种强大的编程语言,其在多线程编程方面表现出色。
为了实现多线程,需要使用C++中的线程库。
下面是C++多线程实现方法的详细介绍。
1. 创建线程要创建一个线程,需要使用C++中的thread类。
创建线程的基本语法如下:```#include <thread>void myFunction(){// do something}int main(){std::thread t(myFunction); // 创建线程t.join(); // 等待线程结束return 0;}```2. 传递参数如果需要向线程传递参数,可以通过将参数传递给线程构造函数来实现。
```#include <thread>void myFunction(int x){// do something with x}int main(){int x = 42;std::thread t(myFunction, x); // 向线程传递参数t.join(); // 等待线程结束return 0;}```3. 多线程同步在多线程编程中,同步是一项重要的任务。
C++中提供了多种同步机制,如互斥锁和条件变量。
互斥锁是一种保护共享资源的机制。
在访问共享资源之前,线程必须获取互斥锁。
在完成操作后,线程必须释放互斥锁,以便其他线程可以访问共享资源。
```#include <mutex>std::mutex myMutex; // 定义互斥锁void myFunction(){myMutex.lock(); // 获取互斥锁// do something with shared resourcemyMutex.unlock(); // 释放互斥锁}int main(){std::thread t1(myFunction);std::thread t2(myFunction);t1.join();t2.join();return 0;}```条件变量是一种允许线程在特定条件下等待的机制。
多线程的四种实现方式
多线程是指在一个进程中同时运行多个线程,以提高程序的运行
效率。
多线程的实现方式有以下四种:
1. 继承Thread类
通过继承Thread类,重写run方法来实现多线程。
可以通过创
建Thread对象并调用start方法来启动线程。
2. 实现Runnable接口
通过实现Runnable接口,重写run方法来实现多线程。
可以通
过创建Thread对象并将Runnable对象传递给其构造函数来启动线程。
3. 实现Callable接口
通过实现Callable接口,重写call方法来实现多线程。
可以通
过创建FutureTask对象并将Callable对象传递给其构造函数来启动
线程。
4. 线程池
线程池可以提高线程的使用效率,避免线程频繁创建和销毁的开销。
可以通过ThreadPoolExecutor类来创建线程池,可以指定线程池
的大小、工作队列以及拒绝策略等参数。
android 多线程面试题Android多线程面试题Android多线程是一个重要的技术,对于开发者来说,掌握多线程编程是非常必要的。
在Android面试中,经常会出现与多线程相关的问题。
下面将介绍一些常见的Android多线程面试题,希望能够帮助你在面试中更好地回答问题。
1. 什么是多线程?多线程是指在一个进程中同时执行多个任务的技术。
在Android中,多线程可以实现在后台同时进行多个任务,以提升用户体验和应用性能。
2. 在Android中有哪些实现多线程的方式?在Android中,有以下几种实现多线程的方式:a. 使用Thread类:可以通过继承Thread类或者创建Thread匿名内部类的方式来创建线程对象,重写run()方法来定义线程执行的操作。
b. 使用Runnable接口:通过创建一个实现Runnable接口的类的实例,将其作为参数传递给Thread类的构造函数来创建线程。
c. 使用HandlerThread类:HandlerThread是继承自Thread的一个类,它内部封装了一个Looper和Handler,可以方便地实现线程间的通信。
d. 使用AsyncTask类:AsyncTask是一个封装了异步操作的类,它可以在后台执行耗时操作,并在主线程更新UI。
3. 什么是主线程和子线程?主线程是指应用程序的主要执行线程,也称为UI线程。
它负责处理用户交互、更新UI等操作。
子线程是在主线程之外创建的线程,用于执行一些耗时的操作,以保证主线程不会被阻塞。
4. 如何在子线程中更新UI?在Android中,UI更新必须在主线程中进行,但有时需要在子线程中执行一些耗时操作。
可以通过以下几种方式在子线程中更新UI:a. 使用Handler:可以在子线程中通过Handler发送消息给主线程,然后在主线程中通过Handler处理消息,更新UI。
b. 使用runOnUiThread()方法:可以在子线程中通过Activity的runOnUiThread()方法来直接更新UI。
c 多线程实现的四种方式C语言是一种非常流行的编程语言,它可以用来实现多线程编程。
多线程编程可以让你的程序更高效、更快速地运行,因为它可以同时执行多个任务。
在这篇文章中,我们将介绍 C 多线程实现的四种方式。
1. 使用 pthread 库pthread 是一个 POSIX 标准定义的多线程库,它提供了一套API 接口,可以用来实现多线程编程。
使用 pthread,你可以创建多个线程并且控制它们的行为。
这种方式是 C 语言实现多线程的最常用方式之一。
2. 使用 OpenMP 库OpenMP 是一个开源的多线程库,它可以用来在 C 语言中实现多线程编程。
OpenMP 提供了一套 API 接口,可以让你更方便地编写并行程序。
使用 OpenMP,你可以使用 #pragma 指令来控制并行执行的代码块。
3. 使用 POSIX 线程POSIX 线程是一种 POSIX 标准定义的多线程接口,它可以用来实现多线程编程。
与 pthread 类似,POSIX 线程提供了一套 API 接口,可以让你更方便地编写多线程程序。
4. 使用 Windows 线程如果你在 Windows 操作系统上编写 C 语言程序,你可以使用Windows 线程来实现多线程编程。
Windows 线程提供了一套 API 接口,可以让你在 Windows 平台上创建多个线程并且控制它们的行为。
总结以上是 C 多线程实现的四种方式。
在选择使用哪种方式时,你应该考虑自己的需求和使用的操作系统。
不同的方式会有不同的 API 接口、性能和可移植性。
如果你需要了解更多关于 C 多线程编程的知识,可以参考相关的书籍和教程。
PYQT5实现多线程的方法在PyQt5中,实现多线程可以通过以下几种方法:1. 使用`QThread`类:`QThread`是PyQt5提供的多线程编程的基类。
我们需要创建一个继承自`QThread`的子类,并重写其`run(`方法,在该方法中编写我们想要在新线程执行的代码。
以下是一个简单的示例:```pythonfrom PyQt5.QtCore import QThreadclass MyThread(QThread):def run(self):#执行需要在新线程中运行的代码pass#在主线程中创建并启动新线程my_thread = MyThreadmy_thread.start```注意,在新线程中不能直接操作UI界面,因为UI界面只能在主线程中更新。
如果需要在新线程中更新UI界面,可以通过信号与槽机制进行通信。
2. 使用`QObject`的`moveToThread(`方法:另一种创建多线程的方法是,将一个继承自`QObject`的对象移动到新线程中执行。
以下是一个简单的示例:```pythonfrom PyQt5.QtCore import QThread, QObjectclass Worker(QObject):def __init__(self):super(.__init__def do_work(self):#执行需要在新线程中运行的代码pass# 在主线程中创建Worker对象worker = Worker# 在主线程中创建QThread对象,并将Worker对象移动到新线程中thread = QThreadworker.moveToThread(thread)# 连接Worker对象的do_work信号与thread的started槽函数thread.started.connect(worker.do_work)#启动新线程thread.start```可以通过信号与槽机制在主线程和新线程之间进行通信。
C多线程函数如何传参数和返回值在C多线程编程中,可以通过以下几种方式来传递参数和获取返回值:1.传递参数:-通过结构体:可以使用一个结构体来封装所有需要传递的参数,并将该结构体作为线程的参数传递。
在线程函数中,可以通过强制类型转换将参数还原为原始类型,并使用其中的成员变量。
-通过指针:可以将需要传递的参数作为指针进行传递,线程函数在收到指针后,可以通过解引用来获得参数值,或者使用指针指向的数据。
-通过全局变量:可以将参数设置为全局变量,在线程函数中直接使用该全局变量进行操作。
需要注意的是,多个线程同时修改全局变量时可能会发生竞争条件,需要使用互斥锁来保护。
2.获取返回值:-通过指针传递返回值:可以将需要返回的值设置为指针参数,线程函数在执行完毕后将结果写入该指针指向的内存位置。
主线程可以通过读取该内存位置来获取返回值。
-通过全局变量:可以将返回值设置为全局变量,在线程函数执行完毕后,在全局变量中存储结果。
主线程可以直接读取该全局变量来获取返回值。
但是同样需要注意并发操作时的竞争条件问题。
- 使用线程函数返回值:线程函数本身是可以返回一个值的,这个返回值可以通过pthread_join函数来获取。
主线程可以通过调用pthread_join函数来等待子线程执行完毕,并获取线程函数的返回值。
需要注意的是,在C多线程编程中,传递参数和获取返回值都需要考虑数据的一致性和并发性,尤其是多个线程同时对数据进行修改时可能会导致的问题。
可以使用互斥锁来保护对共享数据的访问,或者使用其他的线程同步机制来协调线程之间的执行顺序,并保证数据的一致性。
综上所述,C多线程函数可以通过结构体、指针、全局变量等方式来传递参数和获取返回值。
通过合理的设计和使用线程同步机制,可以确保线程之间的安全操作,并实现多线程程序的正确执行。
threading 穿参数在Python中,threading 模块允许你创建和管理线程。
当你想在多个线程之间传递参数时,可以使用多种方式。
这里是一些方法来穿参数(传递参数)给线程:1. 通过target函数最常见的方式是在定义线程时要执行的函数时,将其作为target参数传递给Thread 类,并在该函数中定义所需的参数。
pythonimport threadingdef worker_function(arg1, arg2):# 处理参数print(f"Working with {arg1} and {arg2}")# 创建线程实例,并传递参数thread = threading.Thread(target=worker_function, args=("Hello", 123)) thread.start()thread.join()2. 使用类你也可以定义一个线程类,并在__init__方法中接收参数。
pythonimport threadingclass WorkerThread(threading.Thread):def __init__(self, arg1, arg2):threading.Thread.__init__(self)self.arg1 = arg1self.arg2 = arg2def run(self):# 使用self.arg1和self.arg2print(f"Working with {self.arg1} and {self.arg2}")# 创建线程实例,并传递参数thread = WorkerThread("Hello", 123)thread.start()thread.join()注意事项当在线程间传递参数时,确保这些参数是线程安全的,或者它们在使用时不会被多个线程同时修改。
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对象并启动了一个线程。
多线程实现的⼏种⽅式多线程实现⼀共有四种⽅式,如下图:- pthread的使⽤ - 定义pthreadtypedef __darwin_pthread_t pthread_t; - 创建pthreadint pthread_create(pthread_t * __restrict, const pthread_attr_t * __restrict,void *(*)(void *), void * __restrict); - 范例void * run(void *param){for (NSInteger i = 0; i<50000; i++) {NSLog(@"------buttonClick---%zd--%@", i, [NSThread currentThread]);}return NULL;}- (IBAction)buttonClick:(id)sender {pthread_t thread;pthread_create(&thread, NULL, run, NULL);pthread_t thread2;pthread_create(&thread2, NULL, run, NULL);}- NSThread - 创建和启动线程NSThread *thread = [[NSThread alloc] initWithTarget:self selector:@selector(run) object:nil];[thread start]; - 主线程相关⽤法+ (NSThread *)mainThread; // 获得主线程- (BOOL)isMainThread; // 是否为主线程+ (BOOL)isMainThread; // 是否为主线程 - 获取当前线程NSThread *current = [NSThread currentThread]; - 线程的名字- (void)setName:(NSString *)n;- (NSString *)name; - 其它⽅式创建线程 - 创建线程后⾃动启动线程[NSThread detachNewThreadSelector:@selector(run) toTarget:self withObject:nil]; - 隐式创建并启动线程[self performSelectorInBackground:@selector(run) withObject:nil]; - 上述2种创建线程⽅式的优缺点 - 优点:简单快捷 - 缺点:⽆法对线程进⾏更详细的设置 - 线程的状态NSThread *thread = [[NSThread alloc] initWithTarget:self selector:@selector(run) object:nil];[thread start]; - 阻塞(暂停)线程+ (void)sleepUntilDate:(NSDate *)date;+ (void)sleepForTimeInterval:(NSTimeInterval)ti;// 进⼊阻塞状态 - 强制停⽌线程+ (void)exit;// 进⼊死亡状态注意:⼀旦线程停⽌(死亡)了,就不能再次开启任务 - 多线程的隐患 - 资源共享 - 1块资源可能会被多个线程共享,也就是多个线程可能会访问同⼀块资源 - ⽐如多个线程访问同⼀个对象、同⼀个变量、同⼀个⽂件 - 当多个线程访问同⼀块资源时,很容易引发数据错乱和数据安全问题 - 解决⽅法:互斥锁 - 互斥锁使⽤格式@synchronized(锁对象) { // 需要锁定的代码 }注意:锁定1份代码只⽤1把锁,⽤多把锁是⽆效的 - 互斥锁的优缺点 - 优点:能有效防⽌因多线程抢夺资源造成的数据安全问题 - 缺点:需要消耗⼤量的CPU资源 - 互斥锁的使⽤前提:多条线程抢夺同⼀块资源 - 相关专业术语:线程同步 - 线程同步的意思是:多条线程在同⼀条线上执⾏(按顺序地执⾏任务) - 互斥锁,就是使⽤了线程同步技术 - 原⼦和⾮原⼦属性 - OC在定义属性时有nonatomic和atomic两种选择 - atomic:原⼦属性,为setter⽅法加锁(默认就是atomic) - nonatomic:⾮原⼦属性,不会为setter⽅法加锁 - nonatomic和atomic对⽐ - atomic:线程安全,需要消耗⼤量的资源 - nonatomic:⾮线程安全,适合内存⼩的移动设备 - iOS开发的建议 - 所有属性都声明为nonatomic - 尽量避免多线程抢夺同⼀块资源 - 尽量将加锁、资源抢夺的业务逻辑交给服务器端处理,减⼩移动客户端的压⼒- GCD的使⽤ - 什么是GCD - 全称是Grand Central Dispatch,可译为“⽜逼的中枢调度器” - 纯C语⾔,提供了⾮常多强⼤的函数 - GCD的优势 - GCD是苹果公司为多核的并⾏运算提出的解决⽅案 - GCD会⾃动利⽤更多的CPU内核(⽐如双核、四核) - GCD会⾃动管理线程的⽣命周期(创建线程、调度任务、销毁线程) - 程序员只需要告诉GCD想要执⾏什么任务,不需要编写任何线程管理代码 - GCD中有2个核⼼概念 - 任务:执⾏什么操作 - 队列:⽤来存放任务 - GCD的使⽤就2个步骤 - 定制任务 - 确定想做的事情 - 将任务添加到队列中 - GCD会⾃动将队列中的任务取出,放到对应的线程中执⾏ - 任务的取出遵循队列的FIFO原则:先进先出,后进后出 - GCD中有2个⽤来执⾏任务的常⽤函数 - ⽤同步的⽅式执⾏任务// queue:队列 block:任务dispatch_sync(dispatch_queue_t queue, dispatch_block_t block); - ⽤异步的⽅式执⾏任务dispatch_async(dispatch_queue_t queue, dispatch_block_t block); - 同步和异步的区别 - 同步:只能在当前线程中执⾏任务,不具备开启新线程的能⼒ - 异步:可以在新的线程中执⾏任务,具备开启新线程的能⼒ - GCD中还有个⽤来执⾏任务的函数,在前⾯的任务执⾏结束后它才执⾏,⽽且它后⾯的任务等它执⾏完成之后才会执⾏:// 这个queue不能是全局的并发队列dispatch_barrier_async(dispatch_queue_t queue, dispatch_block_t block); - 队列的类型 - GCD的队列可以分为2⼤类型 - 并发队列(Concurrent Dispatch Queue) - 可以让多个任务并发(同时)执⾏(⾃动开启多个线程同时执⾏任务) - 并发功能只有在异步(dispatch_async)函数下才有效 - 串⾏队列(Serial Dispatch Queue) - 让任务⼀个接着⼀个地执⾏(⼀个任务执⾏完毕后,再执⾏下⼀个任务) - 并发队列 - ⾃⼰创建的 - 全局 - 串⾏队列 - 主队列 - ⾃⼰创建的 - 同步和异步主要影响:能不能开启新的线程 - 同步:只是在当前线程中执⾏任务,不具备开启新线程的能⼒ - 异步:可以在新的线程中执⾏任务,具备开启新线程的能⼒ - 并发和串⾏主要影响:任务的执⾏⽅式 - 并发:允许多个任务并发(同时)执⾏ - 串⾏:⼀个任务执⾏完毕后,再执⾏下⼀个任务 - 并发队列// 使⽤dispatch_queue_create函数创建队列dispatch_queue_tdispatch_queue_create(const char *label, // 队列名称dispatch_queue_attr_t attr); // 队列的类型// 创建并发队列dispatch_queue_t queue = dispatch_queue_create("com.samyang.queue", DISPATCH_QUEUE_CONCURRENT); // GCD默认已经提供了全局的并发队列,供整个应⽤使⽤,可以⽆需⼿动创建使⽤dispatch_get_global_queue函数获得全局的并发队列dispatch_queue_t dispatch_get_global_queue(dispatch_queue_priority_t priority, // 队列的优先级unsigned long flags); // 此参数暂时⽆⽤,⽤0即可// 获得全局并发队列dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);// 全局并发队列的优先级#define DISPATCH_QUEUE_PRIORITY_HIGH 2 // ⾼#define DISPATCH_QUEUE_PRIORITY_DEFAULT 0 // 默认(中)#define DISPATCH_QUEUE_PRIORITY_LOW (-2) // 低#define DISPATCH_QUEUE_PRIORITY_BACKGROUND INT16_MIN // 后台 - 串⾏队列// GCD中获得串⾏有2种途径// 使⽤dispatch_queue_create函数创建串⾏队列// 创建串⾏队列(队列类型传递NULL或者DISPATCH_QUEUE_SERIAL)dispatch_queue_t queue = dispatch_queue_create("com.samyang.queue", NULL);/*使⽤主队列(跟主线程相关联的队列)主队列是GCD⾃带的⼀种特殊的串⾏队列放在主队列中的任务,都会放到主线程中执⾏使⽤dispatch_get_main_queue()获得主队列*/dispatch_queue_t queue = dispatch_get_main_queue(); - 各种队列的执⾏效果- 注意:使⽤sync函数往当前串⾏队列中添加任务,会卡住当前的串⾏队列 - 延时执⾏ - iOS常见的延时执⾏// 调⽤NSObject的⽅法[self performSelector:@selector(run) withObject:nil afterDelay:2.0];// 2秒后再调⽤self的run⽅法// 使⽤GCD函数dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2.0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ // 2秒后执⾏这⾥的代码...});// 使⽤NSTimer[NSTimer scheduledTimerWithTimeInterval:2.0 target:self selector:@selector(test) userInfo:nil repeats:NO]; - ⼀次性代码(⽐如说单例模式singleton)// 使⽤dispatch_once函数能保证某段代码在程序运⾏过程中只被执⾏1次static dispatch_once_t onceToken;dispatch_once(&onceToken, ^{// 只执⾏1次的代码(这⾥⾯默认是线程安全的)}); - 快速迭代// 使⽤dispatch_apply函数能进⾏快速迭代遍历dispatch_apply(10, dispatch_get_global_queue(0, 0), ^(size_t index){// 执⾏10次代码,index顺序不确定}); - 队列组 -有这么1种需求 - ⾸先:分别异步执⾏2个耗时的操作 - 其次:等2个异步操作都执⾏完毕后,再回到主线程执⾏操作// 如果想要快速⾼效地实现上述需求,可以考虑⽤队列组dispatch_group_t group = dispatch_group_create();dispatch_group_async(group, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{// 执⾏1个耗时的异步操作});dispatch_group_async(group, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{// 执⾏1个耗时的异步操作});dispatch_group_notify(group, dispatch_get_main_queue(), ^{// 等前⾯的异步操作都执⾏完毕后,回到主线程...});- NSOperationNSOperationQueue的队列类型主队列[NSOperationQueue mainQueue]凡是添加到主队列中的任务(NSOperation),都会放到主线程中执⾏⾮主队列(其他队列)[[NSOperationQueue alloc] init]同时包含了:串⾏、并发功能添加到这种队列中的任务(NSOperation),就会⾃动放到⼦线程中执⾏NSOperation的作⽤配合使⽤NSOperation和NSOperationQueue也能实现多线程编程NSOperation和NSOperationQueue实现多线程的具体步骤先将需要执⾏的操作封装到⼀个NSOperation对象中然后将NSOperation对象添加到NSOperationQueue中系统会⾃动将NSOperationQueue中的NSOperation取出来将取出的NSOperation封装的操作放到⼀条新线程中执⾏NSOperation的⼦类NSOperation是个抽象类,并不具备封装操作的能⼒,必须使⽤它的⼦类使⽤NSOperation⼦类的⽅式有3种NSInvocationOperationNSBlockOperation⾃定义⼦类继承NSOperation,实现内部相应的⽅法NSInvocationOperation创建NSInvocationOperation对象- (id)initWithTarget:(id)target selector:(SEL)sel object:(id)arg;调⽤start⽅法开始执⾏操作- (void)start;⼀旦执⾏操作,就会调⽤target的sel⽅法注意默认情况下,调⽤了start⽅法后并不会开⼀条新线程去执⾏操作,⽽是在当前线程同步执⾏操作只有将NSOperation放到⼀个NSOperationQueue中,才会异步执⾏操作NSBlockOperation创建NSBlockOperation对象+ (id)blockOperationWithBlock:(void (^)(void))block; - 通过addExecutionBlock:⽅法添加更多的操作- (void)addExecutionBlock:(void (^)(void))block;注意:只要NSBlockOperation封装的操作数 > 1,就会异步执⾏ - NSOperationQueue - NSOperationQueue的作⽤ - NSOperation可以调⽤start⽅法来执⾏任务,但默认是同步执⾏的 - 如果将NSOperation添加到NSOperationQueue(操作队列)中,系统会⾃动异步执⾏NSOperation中的操作 - 添加操作到NSOperationQueue中- (void)addOperation:(NSOperation *)op;- (void)addOperationWithBlock:(void (^)(void))block; - 最⼤并发数 - 什么是并发数 - 同时执⾏的任务数 - ⽐如,同时开3个线程执⾏3个任务,并发数就是3 - 最⼤并发数的相关⽅法- (NSInteger)maxConcurrentOperationCount;- (void)setMaxConcurrentOperationCount:(NSInteger)cnt; - 队列的取消、暂停、恢复取消队列的所有操作- (void)cancelAllOperations;- 提⽰:也可以调⽤NSOperation的- (void)cancel⽅法取消单个操作 - 暂停和恢复队列- (void)setSuspended:(BOOL)b; // YES代表暂停队列,NO代表恢复队列- (BOOL)isSuspended; - 操作优先级 设置NSOperation在queue中的优先级,可以改变操作的执⾏优先级- (NSOperationQueuePriority)queuePriority;- (void)setQueuePriority:(NSOperationQueuePriority)p; - 优先级的取值NSOperationQueuePriorityVeryLow = -8L,NSOperationQueuePriorityLow = -4L,NSOperationQueuePriorityNormal = 0,NSOperationQueuePriorityHigh = 4,NSOperationQueuePriorityVeryHigh = 8 - 操作依赖 - NSOperation之间可以设置依赖来保证执⾏顺序 - ⽐如⼀定要让操作A执⾏完后,才能执⾏操作B,可以这么写[operationB addDependency:operationA]; // 操作B依赖于操作A - 可以在不同queue的NSOperation之间创建依赖关系 注意:不能相互依赖,⽐如A依赖B,B依赖A - 操作的监听 - 可以监听⼀个操作的执⾏完毕- (void (^)(void))completionBlock;- (void)setCompletionBlock:(void (^)(void))block; - ⾃定义NSOperation - ⾃定义NSOperation的步骤很简单 - 重写- (void)main⽅法,在⾥⾯实现想执⾏的任务 - 重写- (void)main⽅法的注意点 - ⾃⼰创建⾃动释放池(因为如果是异步操作,⽆法访问主线程的⾃动释放池) - 经常通过- (BOOL)isCancelled⽅法检测操作是否被取消,对取消做出响应。
执行带一个参数的委托函数
#region执行带一个参数的多线程
Thread mythread = new Thread(new ParameterizedThreadStart(Calculate));
mythread.IsBackground = true;
mythread.Start(500);
#endregion
private void Calculate(object Max) //带一个参数的委托函数
{
int max = (int)Max;
Stopwatch stopwatch = Stopwatch.StartNew();
for (int i = 0; i < max; i++)
{
Thread.Sleep(5);
}
stopwatch.Stop();
long lSearchTime = stopwatch.ElapsedMilliseconds;
MessageBox.Show(lSearchTime.ToString() + "毫秒");
}
执行带多个参数的委托函数
方式一:定义一个类,将要传的参数设置为类的属性,然后将参数值赋值给类的属性,将类作为一个参数进行传达,以下代码通过两个参数示例,多个参数一样,代码如下
class MyClass
{
public int Max { get; set; }
public int Min { get; set; }
}
#region第一种方式:执行带多个参数的多线程
MyClass model = new MyClass();
model.Max = 500;
model.Min = 0;
Thread mythread1 = new Thread(new ParameterizedThreadStart(CalculateTwo));
mythread1.IsBackground = true;
mythread1.Start(model);
#endregion
private void CalculateTwo(object Myclass) //带多个参数的委托函数
{
MyClass model = (MyClass)Myclass;
Stopwatch stopwatch = Stopwatch.StartNew();
for (int i = model.Min; i < model.Max; i++)
{
Thread.Sleep(5);
}
stopwatch.Stop();
long lSearchTime = stopwatch.ElapsedMilliseconds;
MessageBox.Show(lSearchTime.ToString() + "毫秒");
}
方式二:lambda表达式的方式,简单方便,代码如下:
#region第二种方式:执行带多个参数的多线程
Thread mythread2 = new Thread(() => CalculateThree(500, 0)); mythread2.IsBackground = true; //設置為後臺線程,程式關閉后進程也關閉,如果不設置true,則程式關閉,此線程還在內存,不會關閉 mythread2.Start();
#endregion
private void CalculateThree(int Max,int Min) //带多个参数的委托函数
{
Stopwatch stopwatch = Stopwatch.StartNew();
for (int i = Min; i < Max; i++)
{
Thread.Sleep(5);
}
stopwatch.Stop();
long lSearchTime = stopwatch.ElapsedMilliseconds;
MessageBox.Show(lSearchTime.ToString() + "毫秒");
}。