我是 Python 新手。我正在尝试做某事,但不确定是否可能。我想创建一个运行 1 个函数的线程,并在完成后运行另一个函数。
例如
thread.start_new_thread( func1 )
//Run this thread only after the first one was finished
thread.start_new_thread( func2 )
Run Code Online (Sandbox Code Playgroud)
是否可以用 1 个线程来完成?或者我需要创建 2 个线程?我应该怎么办?
我的项目需要大量的异步编程,所以我选择AKKA平台,因为使用actor模型可以像编写同步代码一样实现异步系统,而不必担心线程问题。一切正常,直到我遇到以下问题(演示代码):
import akka.actor.AbstractActor;
import akka.japi.pf.ReceiveBuilder;
import java.util.concurrent.locks.ReentrantLock;
public class TestActor extends AbstractActor {
private final ReentrantLock lock = new ReentrantLock();
@Override
public Receive createReceive() {
return ReceiveBuilder.create()
.matchEquals("lock", s -> lock.lock())
.matchEquals("unlock", s -> lock.unlock())
.build();
}
}
Run Code Online (Sandbox Code Playgroud)
首先发送“锁定”消息,然后发送“解锁”消息,在收到发送消息后尝试解锁时,抛出了一个IllegalMonitorStateException
,我发现这是由于不同的消息实际上由不同的线程处理,s -> lock.lock()
并且s -> lock.unlock()
是在不同的线程中执行,因此IllegalMonitorStateException
抛出。
我之前的假设是,演员的所有操作都在一个线程中执行,因此它是完全线程安全的,不必担心线程问题。由于我在项目中广泛使用 AKKA,现在我非常担心并且不清楚第一剂在使用 AKKA 时何时需要考虑线程问题。例如,在以下演示代码中:
public class TestActor1 extends AbstractActor {
private int count = 0;
private Map<Integer, Integer> map = new HashMap<>();
@Override
public Receive createReceive() {
return ReceiveBuilder.create() …
Run Code Online (Sandbox Code Playgroud) 这是在java中。我的程序的目的是每秒多次捕获计算机屏幕的屏幕截图,并找到具有特殊红色阴影的所有像素。然后,它找到所有红色像素的平均位置。
为了提高图像处理的效率,我创建了 3 个线程,每个线程处理 1/4 的像素。这些线程加上原始线程将因此处理所有像素。但是,我的 avgLocation() 方法中不断出现错误。这是一个空指针异常,我认为这是因为其他线程正在更改包含所有红色像素的列表的大小,这导致程序访问不存在的像素的数据。为了解决这个问题,我在 Thread2 的代码之后在 Thread1 和 Thread2 上使用了 .join,然后在 Thread3 的代码段之后使用了 .join。因此,在调用 avgLocation 方法之前应该连接所有线程,但每当屏幕上出现特定的红色阴影时,它仍然会给出 NullPointerException。这是堆栈跟踪
Exception in thread "main" java.lang.NullPointerException
at Images.avgLocation(Images.java:151)
at Images.processImage(Images.java:133)
at Images.main(Images.java:169)
Run Code Online (Sandbox Code Playgroud)
151 号线是
xSum += list.get(i)[0];
Run Code Online (Sandbox Code Playgroud)
第 133 行是这是我的代码:
import java.awt.AWTException;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.Robot;
import java.awt.Toolkit;
import java.awt.image.BufferedImage;
import java.awt.image.DataBufferInt;
import java.util.ArrayList;
public class Images {
//takes in an input image and a target color and a bound to check within, returns …
Run Code Online (Sandbox Code Playgroud) 在《清洁代码》一书中有一个我想更好地理解的例子:
public static SimpleDateFormat makeStandardHttpDateFormat() {
// SimpleDateFormat is not thread safe, so we need to create each instance independently
SimpleDateFormat df = new SimpleDateFormat("dd/MMM/yyyy:HH:mm:ss Z");
df.setTimeZone(TimeZone.getTimeZone("GMT"));
return df
}
Run Code Online (Sandbox Code Playgroud)
我读到这SimpleDateFormat
不是线程安全的,因为它:将中间结果存储在实例字段中。因此,如果一个实例被两个线程使用,它们可能会弄乱彼此的结果。现在我感兴趣的是为什么使用静态工厂方法是避免此类SimpleDateFormat
非线程安全类的线程安全问题的一种解决方案(可能不是最好的)?
如果我们有两个线程 A 和 B,为什么创建makeStandardHttpDateFormat()
静态方法会有帮助呢?makeStandardHttpDateFormat()
如果不是静态的,因为我们为每个线程创建了无论如何的新实例,那不是一样吗SimpleDateFormat
?
书中指出
……这个评论是完全合理的。它将防止一些过于急切的程序员以效率的名义使用静态初始化程序。
静态方法真的那么慢吗?这句话是什么意思呢?为什么仅仅因为注释就应该阻止“过于热切的程序员”使用这个静态方法?IDE 可能甚至不会显示注释。但是,它可能会表明该方法是静态的。所以对我来说这个评论毫无意义。至少,不像书中提到的那样。
从std::shared_ptr 线程安全等文章中,我知道 std::shared_ptr 的控制块按标准保证是线程安全的,而指向的实际数据本质上不是线程安全的(即,它是对我来说,作为用户,做到这一点)。
我在研究中未能找到如何保证这一点的答案。我的意思是,具体使用什么机制来确保控制块是线程安全的(因此对象只被删除一次)?
我问这个问题是因为我正在将 newlib-nano C++ 库与 FreeRTOS 一起用于嵌入式系统。这两者本质上并不是为了相互协作而设计的。由于我从未编写过任何代码来确保控制块是线程安全的(例如,没有关键部分或互斥体的代码),因此我只能假设它实际上可能不是 FreeRTOS 线程安全的。
该程序将崩溃,因为线程缠结......一个可能正在推动,而另一个正在尝试擦除。
我怎样才能做到这一点?
#include <thread>
#include <vector>
using namespace std;
vector<int> v_test;
void push()
{
v_test.push_back(0);
}
void erase()
{
if (v_test.size() > 0)
{
v_test.erase(v_test.begin());
}
}
int main()
{
thread w0(push);
thread w1(erase);
while (true) { Sleep(1000); }
return 0;
}
Run Code Online (Sandbox Code Playgroud) 我知道在这里已经多次询问过这种事情,但我仍然没有完全理解ASP中的线程安全性.
C#:Where Util是一个静态类,而List是一个静态List.
Util.theList= new List<Object>();
Util.theList.Add(someObject);
Run Code Online (Sandbox Code Playgroud)
页面加载一次,然后一秒钟后(POSTACK后1秒)填充Util.theList并重新加载页面以与新填充的列表数据绑定:
this.Repeater.DataSource = Util.theList;
this.Repeater.DataBind();
Run Code Online (Sandbox Code Playgroud)
每次填充List时,它都是INSTANTIATED:
Util.theList= new List<Object>();
Run Code Online (Sandbox Code Playgroud)
如果这不是线程安全的,我怎样才能使其线程安全?我不能让列表非静态并且在同一页面上,因为一个单独的问题,如果数据绑定在page_load上,数据每次都会绑定: OnDataBind只在第一次回发时触发
在我的程序中,当用户输入一个号码时,程序通过套接字将该号码发送到服务器,服务器发回与该号码匹配的数据.该数字代表服务级别.具有IncomingReader()实例作为其runnable的线程然后读取从服务器发送的内容,并将其存储为arraylist(详细信息).然后,我使用详细信息arraylist中的数据创建类MyClients的对象.我的问题是创建对象的循环在从服务器读取数据的线程运行之前运行.如何在创建对象的循环之前使从服务器读取的线程运行?代码如下:(我为了简洁而删除了GUI的代码)
public class SearchClients {
JFrame frame;
private JTextField textField;
private JTextField textField_1;
private JTextField textField_2;
private JTextField textField_3;
BufferedReader reader;
PrintWriter writer;
Socket sock;
static ArrayList<String> details = new ArrayList<String>();
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
SearchClients window = new SearchClients();
window.frame.setVisible(true);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
public SearchClients() {
initialize();
}
private void initialize() {
setUpNetworking();
Thread readerThread = new Thread(new IncomingReader());
readerThread.start();
JButton …
Run Code Online (Sandbox Code Playgroud) 我有一个方法,通过3个并发线程在对象实例上调用.我感兴趣的锁是基于价值而不是对象.例如,如果两个线程(T1,T2)正在处理RecordID = 123并且T3正在处理RecordID = 456.该方法应仅锁定T2,T3应继续执行.
目前,我正在使用Lock,但如果T1被锁定,它将锁定T2和T3.
public void doSomething(String id){
try {
lock.lock();
MyRecord r = find(id);
...
....
} finally{
lock.unlock();
}
}
Run Code Online (Sandbox Code Playgroud) 我的getInstance
库中有一个在多个线程中使用的方法,但我不确定它是否是线程安全的:
protected static DataClient instance;
protected DataClient() {
// do stuff here
}
public static synchronized void initialize() {
if (instance == null) {
instance = new DataClient();
}
}
public static DataClient getInstance() {
if (instance == null) {
initialize();
}
return instance;
}
Run Code Online (Sandbox Code Playgroud)
这就是我使用它的方式:
DataClient.getInstance();
Run Code Online (Sandbox Code Playgroud)
这个线程是否安全,如果不是,那么谁能解释为什么它不是线程安全的?
thread-safety ×10
java ×6
c++ ×2
locking ×2
akka ×1
asp.net ×1
c# ×1
concurrency ×1
data-binding ×1
freertos ×1
python ×1
shared-ptr ×1
static ×1
threadpool ×1
vector ×1