今天写题目遇到个问题,是两个线程,一个负责让用户录入邮箱和密码信息,另一个打印一句话提示已发送验证的邮箱。然后就按照需求写完了代码,不过遇到了问题。
图1:
图3:
图一的线程锁加不加都没啥影响,但是图二中的线程锁不加(被注释掉了)就无法正常的运行,结果就像图4一样:
图4:
但是图二中要是加上线程锁之后就能正常运行,结果如图5
图5:
按照我的想法应该都不需要加线程锁啊,因为我在EnterInformationThread类中的run方法的最后给了个sleep()这个时间里,负责打印信息的线程应该完全有时间运行的,可是为什么没有运行呢?希望能够得到解答,感激不尽。
以下是源代码:
public class SendMailThread extends Thread {
/**
* 存放注册成功的邮箱号的集合
*/
private List<String> list;
/**
* 线程监视器
*/
private Object obj;
private Boolean[] key;
public SendMailThread(List<String> list, Object obj, Boolean[] key) {
this.list = list;
this.obj = obj;
this.key = key;
}
@Override
public void run() {
//记录一之前的list的大小
int oldNum = 0;
while (true) {
// synchronized (obj) {
if (key[0]) {
String post = list.get(oldNum);
System.out.println("账号" + post + "激活邮件发送成功");
oldNum = oldNum + 1;
this.key[0] = false;
}
}
// }
// synchronized (obj){
// for (int i = 0; i < 10; i++) {
// System.out.println(key[0]);
// try {
// Thread.sleep(1000);
// } catch (InterruptedException e) {
// e.printStackTrace();
// }
// }
// }}
}
}
public class EnterInformationThread extends Thread {
/**
* 录入信息的工具
*/
private Scanner scanner = new Scanner(System.in);
/**
* 存放是注册成功的邮箱号
*/
/**
* 线程监视器
*/
private Object obj ;
private Boolean[] key;
public EnterInformationThread(Object obj, List<String> list, Boolean[] key) {
this.obj = obj;
this.list = list;
this.key = key;
}
private List<String> list;
@Override
public void run() {
while (true){
System.out.println("请输入邮箱号");
String post = scanner.nextLine();
System.out.println("请输入密码");
String pwd = scanner.nextLine();
// synchronized (obj) {
list.add(post);
System.out.println("邮箱注册成功");
this.key[0] = true;
// }
try {
Thread.sleep(10000);
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
public class Task01 {
public static void main(String[] args) {
ArrayList<String> list = new ArrayList<>();
Object obj = new Object();
Object obj1 = new Object();
Boolean[] key ={false};
EnterInformationThread e = new EnterInformationThread(obj,list,key);
SendMailThread s = new SendMailThread(list,obj1,key);
s.start();
e.start();
}
}
实际上SendMailThread 线程执行了,不过EnterInformationThread线程赋值key[0] = true,SendMailThread 感知不到,所以if (key[0])进不去,把key改成volatile 变量就行了:
private static volatile Boolean[] key ={false};
【以下回答由 GPT 生成】
问题分析:
根据问题描述,你遇到了一个线程问题。你有两个线程,一个线程负责用户输入信息,另一个线程负责打印验证的邮箱信息。你在输入线程中使用了sleep
方法以便给打印线程足够的时间运行。但是你发现如果不加线程锁,打印线程就无法正常运行,加上线程锁后才能正常运行。你希望知道为什么会出现这样的情况。
解决方案:
确保你的代码中使用了正确的线程同步机制。可以使用锁对象来确保线程安全。
给你的打印线程添加一个锁对象,确保同一时间只有一个线程访问该线程。一种常见的方式是使用ReentrantLock
。
import threading
# 创建一个锁对象
lock = threading.Lock()
# 输入线程
class EnterInformationThread(threading.Thread):
def run(self):
# 其他代码
# ...
# 获取锁对象
lock.acquire()
# 打印验证邮箱信息
print("验证邮箱信息已发送")
# 释放锁对象
lock.release()
# 给打印线程足够的时间运行
# 可以根据具体需求设置合适的时间
time.sleep(1)
# 打印线程
class PrintThread(threading.Thread):
def run(self):
# 获取锁对象
lock.acquire()
# 其他打印逻辑
# 释放锁对象
lock.release()
# 创建线程实例
enter_thread = EnterInformationThread()
print_thread = PrintThread()
# 启动线程
enter_thread.start()
print_thread.start()
# 等待线程结束
enter_thread.join()
print_thread.join()
通过使用锁对象确保同一时间只有一个线程访问,你可以解决这个问题。
请注意,这只是一个示例,具体的实现可能会有所不同,具体根据你的实际需求来进行调整和完善。
希望这个解决方案能帮助到你,如果有任何问题,请随时提问。
【相关推荐】