java - 如何在 Android Java 中解决这个并发问题?
问题描述
getArt() 线程在锁定设置为等待 5 秒时锁定,5 秒后线程恢复并返回响应。但是在设置锁后线程被终止。
如何防止线程被终止并强制它在锁等待时继续获取响应,并且在响应返回后,它应该 mLock.notifyAll(); 恢复一切,我的代码有效。
我之前在没有while循环的情况下尝试过它,并且在其他方法将该值用作null之后它确实返回了响应。
请帮忙。
private void setArt(String imgArt){
this.imgArt = imgArt;
}
private void setDone(){
this.done = true;
}
private void getArt(){
mLock = new Object();
Thread thread = new Thread() {
@Override
public void run() {
try {
StringRequest stringRequest = new StringRequest(Request.Method.POST, String.format("%sFetchMP3Image.php", Station_Util.URL),
new Response.Listener<String>() {
@Override
public void onResponse(String response) {
try {
System.out.println("Response received.");
JSONObject Response = new JSONObject(response);
String Status = Response.getString("Response");
if (Status.equals("Success")) {
JSONObject MP3File = Response.getJSONObject("MP3");
String ImageURL = MP3File.getString("ImageURL");
setArt(ImageURL);
mLock.notifyAll();
setDone();
}
} catch (Exception e) {
}
}
},
new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
}
}) {
@Override
protected Map<String, String> getParams() {
Map<String, String> params = new HashMap<String, String>();
params.put("MP3Name", "687956770_1134920615_1196563259.mp3");
return params;
}
};
Volley.newRequestQueue(My_Downloads.this).add(stringRequest);
} catch (Exception e) {
}
}
};
thread.start();
try {
while(!this.done) {
synchronized (mLock) {
System.out.println("Thread Alive Before: " + thread.isAlive());
System.out.println("Thread Alive Before: " + thread.getState());
System.out.println("Thread Alive Before: " + thread.isInterrupted());
mLock.wait(5000);
System.out.println("Thread Alive After: " + thread.isAlive());
System.out.println("Thread Alive After: " + thread.getState());
System.out.println("Thread Alive After: " + thread.isInterrupted());
}
}
SetList();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
编辑 1:我自己解决了它,使用辅助线程来读取值,而不是像以前那样使用 UI 线程。感谢您的投票和任何试图提供帮助的人。
解决方案:
private void setArt(String imgArt){
this.imgArt = imgArt;
}
private void setDone(){
this.done = true;
}
private boolean getDone()
{
return this.done;
}
private void setListed(){
this.listed = true;
}
private boolean getListed(){
return this.listed;
}
private void getArt(){
mLock = new Object();
final Thread thread = new Thread() {
@Override
public void run() {
try {
synchronized (mLock) {
StringRequest stringRequest = new StringRequest(Request.Method.POST, String.format("%sFetchMP3Image.php", Station_Util.URL),
new Response.Listener<String>() {
@Override
public void onResponse(String response) {
try {
System.out.println("Response received: " + response);
JSONObject Response = new JSONObject(response);
String Status = Response.getString("Response");
if (Status.equals("Success")) {
System.out.println("Status: " + Status);
JSONObject MP3File = Response.getJSONObject("MP3");
String ImageURL = MP3File.getString("ImageURL");
System.out.println("ImageURL: " + ImageURL);
setArt(ImageURL);
//mLock.notifyAll();
setDone();
System.out.println("Done in API thread: " + getDone());
}
} catch (Exception e) {
}
}
},
new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
}
}) {
@Override
protected Map<String, String> getParams() {
Map<String, String> params = new HashMap<String, String>();
params.put("MP3Name", "687956770_1134920615_1196563259.mp3");
return params;
}
};
Volley.newRequestQueue(My_Downloads.this).add(stringRequest);
}
} catch(Exception e){
}
}
};
thread.start();
Thread thread2 = new Thread() {
@Override
public void run() {
try {
while (!getDone()) {
synchronized (mLock) {
mLock.wait(250);
System.out.println("API Thread Alive: " + thread.isAlive());
System.out.println("Done in Reading Thread: " + getDone());
new Handler(Looper.getMainLooper()).post(new Runnable() {
@Override
public void run() {
System.out.println("UI Thread Done: " + getDone());
if (getDone()){
setListed();
SetList();
}
}
});
}
}
if (getDone() && !getListed()) {
setListed();
SetList();
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
};
thread2.start();
}
解决方案
您不应该notifyAll
在同步块之外使用该方法。否则,将抛出异常java.lang.IllegalMonitorStateException 。
当您使用该wait
方法时,锁变量将被释放,内部线程将能够使用此监视器。
推荐阅读
- nginx - 修复 Nginx 服务器中的 CORS?
- python - 如何访问 Python 列表中每个循环的三个项目?
- graphql - 我可以在 graphql 游乐场中将一个变量分配给突变的结果吗
- google-apps-script - 脚本要么给出 429 错误(请求太多),要么耗时太长。如何链接函数调用?
- r - 无法对 R 中的数据框应用 t 检验
- sql - BigQuery 插入值 AS,假定缺失列为空
- python - 如何使用opencv自动随机生成类似划痕的线条
- javascript - 表示 GraphQL 模式的最佳方式
- java - Grails 3.x 和 2.5.x 以及 java 11 兼容性问题
- php - 自动同步多个不同表结构的sql表