thread的run方法
Thread之十:停止线程方法汇总

Thread之⼗:停⽌线程⽅法汇总在上篇⽂章《多线程的使⽤——Thread类和Runnable接⼝》中提到中断线程的问题。
在JAVA中,曾经使⽤stop⽅法来停⽌线程,然⽽,该⽅法具有固有的不安全性,因⽽已经被抛弃(Deprecated)。
那么应该怎么结束⼀个进程呢?官⽅⽂档中对此有详细说明:。
在此引⽤stop⽅法的说明:1. Why is Thread.stop deprecated?Because it is inherently unsafe. Stopping a thread causes it to unlock all the monitors that it has locked. (The monitors are unlocked as the ThreadDeath exception propagates up the stack.) If any of the objects previously protected by these monitors were in an inconsistent state, other threads may now view these objects in an inconsistent state. Such objects are said to be damaged. When threads operate on damaged objects, arbitrary behavior can result. This behavior may be subtle and difficult to detect, or it may be pronounced. Unlike other unchecked exceptions, ThreadDeath kills threads silently; thus, the user has no warning that his program may be corrupted. The corruption can manifest itself at any time after the actual damage occurs, even hours or days in the future.⼤概意思是:因为该⽅法本质上是不安全的。
pythonGUI库图形界面开发之PyQt5线程类QThread详细使用方法

pythonGUI库图形界⾯开发之PyQt5线程类QThread详细使⽤⽅法QThread是Qt的线程类中最核⼼的底层类。
由于PyQt的的跨平台特性,QThread要隐藏所有与平台相关的代码要使⽤的QThread开始⼀个线程,可以创建它的⼀个⼦类,然后覆盖其它QThread.run()函数class Thread(QThread):def __init __(self):super(Thread,self).__ init __()def run(self):#线程相关的代码pass接下来创建⼀个新的线程thread = Thread()thread.start()可以看出,PyQt的线程使⽤⾮常简单—-建⽴⼀个⾃定义的类(如thread),⾃我继承⾃QThread ,并实现其run()⽅法即可在使⽤线程时可以直接得到Thread实例,调⽤其start()函数即可启动线程,线程启动之后,会⾃动调⽤其实现的run()的函数,该⽅法就是线程的执⾏函数业务的线程任务就写在run()函数中,当run()退出之后线程就基本结束了,QThread有started和finished信号,可以为这两个信号指定槽函数,在线程启动和结束之时执⾏⼀段代码进⾏资源的初始化和释放操作,更灵活的使⽤⽅法是,在⾃定义的QThread实例中⾃定义信号,并将信号连接到指定的槽函数,当满⾜⼀定的业务条件时发射此信号QThread类中的常⽤⽅法⽅法描述start()启动线程wait()阻⽌线程,直到满⾜如下条件之⼀与此QThread对象关联的线程已完成执⾏(即从run返回时),如果线程完成执⾏,此函数返回True,如果线程尚未启动,也返回True等待时间的单位是毫秒,如果时间是ULONG_MAX(默认值·),则等待,永远不会超时(线程必须从run返回),如果等待超时,此函数将会返回Falsesleep()强制当前线程睡眠多少秒QThread类中的常⽤信号信号描述started在开始执⾏run函数之前,从相关线程发射此信号finished当程序完成业务逻辑时,从相关线程发射此信号QThread的使⽤⽅法实例import sysfrom PyQt5.QtWidgets import *from PyQt5.QtCore import *from PyQt5.QtGui import *class MainWidget(QWidget):def __init__(self, parent=None):super(MainWidget, self).__init__(parent)#设置标题self.setWindowTitle('QThread多线程例⼦')#实例化多线程对象self.thread = Worker()#实例化列表控件与按钮控件self.listFile = QListWidget()self.btnStart = QPushButton('开始')#把控件放置在栅格布局中layout = QGridLayout(self)layout.addWidget(self.listFile, 0, 0, 1, 2)layout.addWidget(self.btnStart, 1, 1)#信号与槽函数的连接self.btnStart.clicked.connect(self.slotStart)self.thread.sinOut.connect(self.slotAdd)def slotAdd(self, file_inf):#向列表控件中添加条⽬self.listFile.addItem(file_inf)def slotStart(self):#开始按钮不可点击,线程开始self.btnStart.setEnabled(False)self.thread.start()class Worker(QThread):sinOut = pyqtSignal(str)def __init__(self, parent=None):super(Worker, self).__init__(parent)#设置⼯作状态与初始num数值self.working = Trueself.num = 0def __del__(self):#线程状态改变与线程终⽌self.working = Falseself.wait()def run(self):while self.working == True:#获取⽂本file_str = 'File index{0}'.format(self.num)self.num += 1# 发射信号self.sinOut.emit(file_str)# 线程休眠2秒self.sleep(2)if __name__ == '__main__':app = QApplication(sys.argv)demo = MainWidget()demo.show()sys.exit(app.exec_())运⾏效果图如下代码分析在这个例⼦中,单击开始按钮,会在后台定时读取数据,并把返回的数据显⽰在界⾯中,⾸先使⽤以下代码进⾏布局,把列表控件和按钮控件放在栅格布局管理器中#实例化列表控件与按钮控件self.listFile = QListWidget()self.btnStart = QPushButton('开始')#把控件放置在栅格布局中layout = QGridLayout(self)layout.addWidget(self.listFile, 0, 0, 1, 2)layout.addWidget(self.btnStart, 1, 1)然后将按钮的clicked信号连接到槽函数,单击开始触发槽函数self.btnStart.clicked.connect(self.slotStart)def slotStart(self):#开始按钮不可点击,线程开始self.btnStart.setEnabled(False)self.thread.start()⽐较复杂的是线程的信号,将线程的sinOut信号连接到slotAdd()槽函数,SlotAdd()函数负责在列表控件中动态添加字符串条⽬self.thread.sinOut.connect(self.slotAdd)def slotAdd(self,file_inf):#向列表控件中添加条⽬self.listFile.addItem(file_inf)定义⼀个线程类,继承⾃QThread,当线程启动时,执⾏run()函数class Worker(QThread):sinOut = pyqtSignal(str)def __init__(self, parent=None):super(Worker, self).__init__(parent)#设置⼯作状态与初始num数值self.working = Trueself.num = 0def __del__(self):#线程状态改变与线程终⽌self.working = Falseself.wait()def run(self):while self.working == True:#获取⽂本file_str = 'File index{0}'.format(self.num)self.num += 1# 发射信号self.sinOut.emit(file_str)# 线程休眠2秒self.sleep(2)多线程失败案例import sysfrom PyQt5.QtWidgets import *from PyQt5.QtCore import *from PyQt5.QtGui import *global secsec=0def setTime():global secsec+=1#Led显⽰数字+1lcdNumber.display(sec)def work():#计时器每秒计数timer.start(1000)for i in range(200000000):passtimer.stop()if __name__ == '__main__':app=QApplication(sys.argv)top=QWidget()top.resize(300,120)#垂直布局layout=QVBoxLayout(top)#添加⼀个显⽰⾯板lcdNumber=QLCDNumber()layout.addWidget(lcdNumber)button=QPushButton('测试')layout.addWidget(button)timer=QTimer()#每次计时结束,触发setTimetimer.timeout.connect(setTime)button.clicked.connect(work)top.show()sys.exit(app.exec_())失败效果图如下长时间停留在此界⾯,知道多线程任务完成后,此界⾯才会动,当耗时程序⾮常⼤时,就会造成程序运⾏失败的假象,实际还是在后台运⾏的,只是没有显⽰在主窗⼝的界⾯上,当然⽤户体验也就⾮常差,那么如何解决这个问题呢,下⾯实例三进⾏解答分离UI主线程与⼯作线程实例import sysfrom PyQt5.QtCore import *from PyQt5.QtGui import *from PyQt5.QtWidgets import *global secsec = 0class WorkThread(QThread):#实例化⼀个信号对象trigger = pyqtSignal()def __int__(self):super(WorkThread, self).__init__()def run(self):#开始进⾏循环for i in range(2000000000):pass# 循环完毕后发出信号self.trigger.emit()def countTime():global secsec += 1# LED显⽰数字+1lcdNumber.display(sec)def work():# 计时器每秒计数timer.start(1000)# 计时开始workThread.start()# 当获得循环完毕的信号时,停⽌计数workThread.trigger.connect(timeStop)def timeStop():#定时器停⽌timer.stop()print("运⾏结束⽤时", lcdNumber.value())global secsec = 0if __name__ == "__main__":app = QApplication(sys.argv)top = QWidget()top.resize(300, 120)# 垂直布局类QVBoxLayoutlayout = QVBoxLayout(top)# 加显⽰屏,按钮到布局中lcdNumber = QLCDNumber()layout.addWidget(lcdNumber)button = QPushButton("测试")layout.addWidget(button)#实例化定时器与多线程类timer = QTimer()workThread = WorkThread()button.clicked.connect(work)# 每次计时结束,触发 countTimetimer.timeout.connect(countTime)top.show()sys.exit(app.exec_())运⾏效果,程序主界⾯的数值会每秒增加1,直到循环结束,这⾥就避免了主界⾯长时间不动的尴尬!QThread线程事件处理实例对于执⾏很耗时的程序来说,由于PyQt需要等待程序执⾏完毕才能进⾏下⼀步,这个过程表现在界⾯上就是卡顿,⽽如果需要执⾏这个耗时程序时不断的刷新界⾯。
python线程的工作原理

python线程的工作原理Python线程的工作原理一、引言Python是一种高级编程语言,具有简洁、易读、易学的特点,因此在各个领域都有广泛的应用。
而线程是Python中实现并发编程的一种方式,可以实现多个任务的并发执行,提高程序的效率。
本文将介绍Python线程的工作原理,包括线程的概念、创建线程的方法、线程的执行过程以及线程同步等内容。
二、线程的概念线程是操作系统能够进行运算调度的最小单位,它被包含在进程中,是进程中的实际运作单位。
与进程相比,线程更轻量级,可以并发执行多个任务,提高程序的响应速度。
在Python中,线程是通过threading模块来实现的。
三、创建线程的方法Python中创建线程有两种方式,一种是通过函数来创建线程,另一种是通过类来创建线程。
1. 通过函数创建线程在Python中,可以使用threading模块的Thread类来创建线程。
首先要定义一个函数,然后将该函数作为参数传递给Thread类的构造方法,即可创建一个线程。
下面是一个简单的示例:```pythonimport threadingdef func():print("This is a thread.")thread = threading.Thread(target=func)thread.start()```在上面的示例中,定义了一个名为func的函数,并将其作为参数传递给Thread类的构造方法,然后调用start方法启动线程。
通过运行上述代码,可以看到输出结果为"This is a thread.",说明线程创建成功并执行了函数。
2. 通过类创建线程除了使用函数创建线程外,还可以通过继承Thread类来创建线程。
首先要定义一个类,继承自Thread类,并重写其run方法,在run方法中实现线程的具体逻辑。
下面是一个示例:```pythonimport threadingclass MyThread(threading.Thread):def run(self):print("This is a thread.")thread = MyThread()thread.start()```在上面的示例中,定义了一个名为MyThread的类,继承自Thread类,并重写了run方法,在run方法中实现了线程的逻辑。
Android常用的开启子线程的方法

Android常用的开启子线程的方法在Android开发中,开启子线程是非常常见的操作。
子线程可以用于执行耗时操作,避免阻塞主线程,提升用户体验。
下面将介绍Android常用的开启子线程的方法。
1. 使用Thread类开启子线程:Thread是Java中最基本的线程类,Android中也可以使用它来开启子线程。
可以通过继承Thread类或者通过创建匿名内部类的方式来实现。
继承Thread类的方式:```public class MyThread extends Threadpublic void ru//子线程要执行的操作}//在主线程中开启子线程MyThread myThread = new MyThread(;myThread.start(;```匿名内部类的方式:```Thread thread = new Thread(new Runnablpublic void ru//子线程要执行的操作}});//在主线程中开启子线程thread.start(;```2. 使用Runnable接口开启子线程:Runnable接口是代表一个任务的接口,可以通过实现这个接口来开启子线程。
与使用Thread类不同的是,使用Runnable接口可以更好地实现线程的复用。
实现Runnable接口的方式:```public class MyRunnable implements Runnablepublic void ru//子线程要执行的操作}//在主线程中开启子线程MyRunnable myRunnable = new MyRunnable(;Thread thread = new Thread(myRunnable);thread.start(;```3. 使用Handler开启子线程:Handler是Android中用于线程间通信的机制,可以通过Handler在子线程中执行一些操作,并将结果传递给主线程。
kthread_run函数 -回复

kthread_run函数-回复kthread_run函数是Linux内核中的一个重要函数,用于创建并执行一个内核线程。
内核线程与用户空间线程不同,它们在内核空间中运行,并且不受用户空间线程管理机制的约束。
在本文中,我们将详细介绍kthread_run函数的作用、参数和实现细节,并解释如何使用它创建和管理内核线程。
首先,让我们来了解kthread_run函数的作用。
kthread_run函数用于创建一个内核线程,并将其添加到内核的调度队列中运行。
这使得内核可以在后台执行一些任务,而不影响用户空间线程的执行。
内核线程的创建和管理是Linux内核中一个重要的功能,它允许内核执行一些需要长时间运行或在后台运行的任务,如设备驱动程序的处理、定期任务的执行、内存管理等。
接下来,我们将详细介绍kthread_run函数的参数和用法。
kthread_run函数的原型定义如下:struct task_struct *kthread_run(int (*thread_fn)(void *data), void *data, const char *namefmt, ...)其中,thread_fn是一个函数指针,指向一个内核线程的入口函数。
该函数会在内核线程启动后被调用。
data是一个可选参数,可以是任意类型的指针,用于传递给thread_fn函数。
namefmt是一个格式化字符串,用于指定内核线程的名称。
要使用kthread_run函数创建内核线程,我们首先需要定义一个内核线程的入口函数。
该函数通常会循环执行某个任务,直到任务完成或被取消。
在入口函数中,我们可以使用一些内核函数来完成任务的具体实现,例如访问设备、读写文件等。
下面是一个简单的示例,演示了如何使用kthread_run函数创建一个内核线程并执行一个简单的任务:include <linux/kthread.h>int my_task(void *data){这里是任务的具体实现...return 0;}在某处的函数中调用kthread_run函数struct task_struct *task;task = kthread_run(my_task, NULL, "my_thread");在上面的示例中,我们定义了一个名为my_task的函数作为内核线程的入口函数。
Thread.join()详解

Thread.join()详解⼀、使⽤⽅式。
join是Thread类的⼀个⽅法,启动线程后直接调⽤,例如:Thread t = new AThread(); t.start(); t.join();⼆、为什么要⽤join()⽅法在很多情况下,主线程⽣成并起动了⼦线程,如果⼦线程⾥要进⾏⼤量的耗时的运算,主线程往往将于⼦线程之前结束,但是如果主线程处理完其他的事务后,需要⽤到⼦线程的处理结果,也就是主线程需要等待⼦线程执⾏完成之后再结束,这个时候就要⽤到join()⽅法了。
三、join⽅法的作⽤在JDk的API⾥对于join()⽅法是:即join()的作⽤是:“等待该线程终⽌”,这⾥需要理解的就是该线程是指的主线程等待⼦线程的终⽌。
也就是在⼦线程调⽤了join()⽅法后⾯的代码,只有等到⼦线程结束了才能执⾏。
四、⽤实例来理解写⼀个简单的例⼦来看⼀下join()的⽤法:1.AThread 类1. BThread类2. TestDemo 类class BThread extends Thread {public BThread() {super("[BThread] Thread");};public void run() {String threadName = Thread.currentThread().getName();System.out.println(threadName + " start.");try {for (int i = 0; i < 5; i++) {System.out.println(threadName + " loop at " + i);Thread.sleep(1000);}System.out.println(threadName + " end.");} catch (Exception e) {System.out.println("Exception from " + threadName + ".run");}}}class AThread extends Thread {BThread bt;public AThread(BThread bt) {super("[AThread] Thread");this.bt = bt;}public void run() {String threadName = Thread.currentThread().getName();System.out.println(threadName + " start.");try {bt.join();System.out.println(threadName + " end.");} catch (Exception e) {System.out.println("Exception from " + threadName + ".run");}}}public class TestDemo {public static void main(String[] args) {String threadName = Thread.currentThread().getName();System.out.println(threadName + " start.");BThread bt = new BThread();AThread at = new AThread(bt);try {bt.start();Thread.sleep(2000);at.start();at.join();} catch (Exception e) {System.out.println("Exception from main");}System.out.println(threadName + " end!");}}打印结果:main start. //主线程起动,因为调⽤了at.join(),要等到at结束了,此线程才能向下执⾏。
java多线程调用方法

java多线程调用方法Java是一种广泛使用的编程语言,它支持多线程编程,使得程序员能够更加高效地利用计算机资源。
在Java中,多线程编程是一种非常常见的编程方式,它可以让程序在不同的线程中同时执行不同的任务,从而提高程序的运行效率和性能。
然而,在实际编程中,多线程编程并不是一件容易的事情。
由于多线程编程涉及到线程之间的同步和互斥问题,如果处理不当,就会导致程序出现各种问题,比如死锁、数据竞争等。
因此,程序员需要掌握一些基本的多线程编程技巧和方法,以确保程序的正确性和稳定性。
本文将介绍Java多线程调用方法的相关知识,包括如何创建线程、如何启动线程、如何停止线程、如何等待线程结束等。
希望能为读者提供一些帮助和指导。
一、创建线程在Java中,创建线程有两种方式:继承Thread类和实现Runnable接口。
继承Thread类是一种比较简单的方式,只需要定义一个类,继承Thread类并重写run()方法即可。
例如:```public class MyThread extends Thread {public void run() {// 线程执行的代码}}```实现Runnable接口是一种更加灵活的方式,它允许多个线程共享同一个Runnable对象,从而实现资源共享。
例如:```public class MyRunnable implements Runnable {public void run() {// 线程执行的代码}}```在创建线程时,需要注意以下几点:1. 线程的启动必须在主线程中进行,否则会导致程序出现异常。
2. 线程的启动必须调用start()方法,而不是run()方法。
如果调用run()方法,会导致线程在主线程中执行,而不是在新线程中执行。
3. 线程的启动顺序是不确定的,由操作系统决定。
二、启动线程在创建线程后,需要启动线程,让它开始执行。
启动线程的方式是调用线程对象的start()方法。
Android的线程使用来更新UI----Thread、Handler、Looper、TimerTask等

方法一:(java习惯,在android不推荐使用)刚刚开始接触android线程编程的时候,习惯好像java一样,试图用下面的代码解决问题new Thread( new Runnable() {public void run() {myView.invalidate();}}).start();可以实现功能,刷新UI界面。
但是这样是不行的,因为它违背了单线程模型:Android UI操作并不是线程安全的并且这些操作必须在UI线程中执行。
方法二:(Thread+Handler)查阅了文档和apidemo后,发觉常用的方法是利用Handler来实现UI线程的更新的。
Handler来根据接收的消息,处理UI更新。
Thread线程发出Handler消息,通知更新UI。
Handler myHandler = new Handler() {public void handleMessage(Message msg) {switch (msg.what) {case TestHandler.GUIUPDATEIDENTIFIER:myBounceView.invalidate();break;}super.handleMessage(msg);}};class myThread implements Runnable {public void run() {while (!Thread.currentThread().isInterrupted()) {Message message = new Message();message.what = TestHandler.GUIUPDATEIDENTIFIER;TestHandler.this.myHandler.sendMessage(message);try {Thread.sleep(100);} catch (InterruptedException e) {Thread.currentThread().interrupt();}}}}以上方法demo看:/blog/411860方法三:(java习惯,不推荐)在Android平台中需要反复按周期执行方法可以使用Java上自带的TimerTask类,Tim erTask相对于Thread来说对于资源消耗的更低,除了使用Android自带的AlarmManager使用Timer定时器是一种更好的解决方法。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
thread的run方法
Thread是Java中一个重要的多线程技术,它允许程序在同一时
间执行多个线程。
一个线程有自己的执行路径,它可以运行在一个程
序中的不同线程上。
线程是一个基本的执行单元,它继承了Thread类,并重写了run()方法,这个方法是线程的主要执行方法。
run()方法是Thread类中最重要的方法之一,它定义了线程的执
行逻辑。
当启动一个线程时,它的run()方法自动被调用,并在这个方法中执行处理逻辑。
在这个方法中,开发者需要实现处理一些具体操
作的代码,比如读取或写入磁盘、网络 I/O、计算等。
下面是使用Thread类中的run()方法来启动一个新线程的基本步骤:
1.定义一个类,它必须继承自Thread类,实现run()方法。
这个run()方法必须包含需要在新线程中执行的代码。
如下所示:
```
public class MyThread extends Thread {
public void run() {
// 线程执行的代码
}
}
```
2.创建一个MyThread类型的对象。
```
MyThread myThread = new MyThread();
```
3.调用MyThread对象的start()方法来运行线程,这会在新线程中调用run()方法。
```
myThread.start();
```
4.当线程完成它的处理逻辑后,run()方法自动结束,并且线程被终止。
如果你希望线程能够一直执行下去,你可以在run()方法中使用一个无限循环。
```
public void run() {
while (true) {
// 线程执行的代码
}
}
```
需要注意的是,多个线程可以共享同一张内存,因此在多线程的应用程序中,要对访问共享资源的代码进行同步。
在Java中,可以使用synchronized关键字来同步线程,保证方法的排它性访问。
总之, Thread类中的run方法是多线程编程中最重要的方法之一。
我们可以继承Thread类,并实现run方法,以在新线程中执行我们的代码。
当然,在使用多线程时,我们需要注意对共享资源的访问,保证线程同步,并保证代码的正确性和效率。