- android - 多次调用 OnPrimaryClipChangedListener
- android - 无法更新 RecyclerView 中的 TextView 字段
- android.database.CursorIndexOutOfBoundsException : Index 0 requested, 光标大小为 0
- android - 使用 AppCompat 时,我们是否需要明确指定其 UI 组件(Spinner、EditText)颜色
这是一个多线程练习,我使用监视器来同步线程。我的监视器或同步没有问题,没有死锁。我想在主线程中创建一些线程。下面的代码生成线程,将它们添加到 ArrayList 并启动它们。使用 switch-case 生成不同的线程。由于每个线程都应添加到 ArrayList 并启动,因此我将这两行放在 switch-case 的末尾,以免在每个 case-state 中编写相同的代码。但这样它就会引发 IllegalThreadStateException。
为了使我的代码正常工作,我可以应用不同的方法,但我对所有这些方法都有一些疑问。哪一种是最合适的方法?
创建一个函数,该函数将创建一个新的 myThread 实例,将其添加到 ArrayList 中并启动它。但由于我必须从 main 调用它,或者它应该是静态的(据我所知,没有充分理由创建静态函数不是一个好习惯),或者我应该像 new myClass().someMethod()
那样调用它,但由于我必须创建许多新线程,它会创建许多 myClass 实例,看起来不太好。
public class myClass {
public static void main(String[] args) {
int scount=10, tcount=5, pcount=5;
final int SIZE = 20;
ArrayList<User> users = new ArrayList<User>();
myMonitor monitor = new myMonitor(SIZE);
User u = null;
int s = 0, t = 0, p = 0; //counters
//GENERATED CASUALLY DIFFERENT TYPE OF THREADS
while(s < scount || t < tcount || p < pcount){
int type = (int)(Math.random() * 3);
switch(type){
case 0:
if(p < pcount){
u = new User(monitor, p, "USER_TYPE_1");
p++;
}
break;
case 1:
if(t < tcount){
u = new User(monitor, p, "USER_TYPE_2");
t++;
}
break;
case 2:
if(s < scount){
u = new User(monitor, p, "USER_TYPE_2");
s++;
}
break;
}
users.add(u);
u.start();
}
}
}
<小时/>
public class User extends Thread{
myMonitor monitor;
final private int number;
final private String type;
final private int k;
final private int MIN = 1;
final private int MAX = 5;
public User(myMonitor monitor, int number, String type) {
this.monitor = monitor;
this.number = number;
this.type = type;
this.k = (int)(Math.random() * ((MAX - MIN) + 1)) + MIN;
}
public int getNumber() {
return number;
}
public String getType() {
return type;
}
@Override
public void run(){
for(int i=0; i<k; i++){
switch(this.type){
case "TYPE1":
monitor.startType1();
break;
case "TYPE2":
monitor.startType2(i);
break;
case "TYPE3":
monitor.startType3();
break;
}
try{
Long duration = (long) Math.ceil(Math.random() * 1000);
Thread.sleep(duration);
System.out.printf("%s-%d used system for the %d.time. Took %d ms\n",
this.type, this.number, i+1, duration);
} catch (InterruptedException e) {
e.printStackTrace();
}
switch(this.type){
case "TYPE1":
monitor.endType1();
break;
case "TYPE2":
monitor.endType2(i);
break;
case "TYPE3":
monitor.endType3();
break;
}
try{
Long duration = (long) Math.ceil(Math.random() * 1000);
Thread.sleep(duration);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.printf("%s-%d finished\n", this.type, this.number);
}
}
最佳答案
让我们进行一个思想实验,Math.random * 3
总是返回 0
- 这是可能的,因为它显然是 random (只是不太可能)。
迭代 1
int s == t == p == 0
我们输入第一种情况,即type == 0
。我们生成一个新的“P”Thread
,并将其添加
到List
中,并start()
它。
p++
迭代 2
int s == t == 0; p == 1
我们输入第一种情况,即type == 0
。我们生成一个新的“P”Thread
,并将其添加
到List
中,并start()
它。
p++
...
迭代 5
int s == t == 0; p == 4
我们输入第一种情况,即type == 0
。我们生成一个新的“P”Thread
,并将其添加
到List
中,并start()
它。
p++
迭代 6
int s == t == 0; p == 5
我们输入第一种情况,即type == 0
。 当 p >= pcount 时我们什么都不做。我们的 thrd
仍然指向我们在迭代 5 中创建的 Thread
。
我们将相同的Thread
添加到List
并start()
它。
IllegalThreadStateException
现在,显然 Math.random * 3
将返回不同的值,但它会返回重复值(并且您的代码是围绕该值设计的) - 所以您将遇到这种情况。
如何避免?好吧,您实际上并不想要生成随机数:
final List<Integer> desiredValues = new ArrayList<>(Arrays.asList(0,0,0,0,0,1,1,1,1,1,2,2,2,2,2,2,2,2,2,2));
Collections.shuffle(desiredValues)
for(final Integer value : desiredValues) {
//case switch
}
关于java - 如何创建线程以避免 IllegalThreadStateException,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36870353/
这个问题是我之前关于堆栈溢出的问题的延续how-to-download-images-asynchronously-from-web-server 。我正在努力在黑莓中制作异步列表。现在它对我来说工作
在我的乒乓球游戏中,每个对象(球和两个 Racket )都在独立线程中运行。 static Ball b = new Ball(195, 145); Thread ball = new Thread(
我的一些用户一直在报告 IllegalThreadStateExceptions,这导致返回以下代码。我无法重新创建它,大多数人都能够毫无问题地执行这部分代码。 代码会定期重新执行,所以旧线程应该被新
我正在尝试多线程,想要实现一个小程序来同时下载多个文件。我创建了一个扩展 Thread 的 FileDownloader 类。 总的来说,我的想法是创建一个包含所有相关 FileDownload 对象
我在 android studio 中有一个 android 应用程序的代码,可以在 1 秒延迟后运行一个方法: new java.util.Timer().schedule(
我一直在研究月球着陆器示例,但在尝试实现关于屏幕时遇到了问题。我将其中一个菜单项(在 onCreateOptionsMenu 中)更改为“关于”选项。选择此选项后,将启动一个新的 Activity 并
这是一个多线程练习,我使用监视器来同步线程。我的监视器或同步没有问题,没有死锁。我想在主线程中创建一些线程。下面的代码生成线程,将它们添加到 ArrayList 并启动它们。使用 switch-cas
import java.io.*; class Sysexecute { public static void main(String args[]) throws IOException,I
我在使用以下代码时遇到 IllegalThreadStateException 异常:我已经启动了这个线程一次(通过使用 thread.start())并再次尝试在另一个地方启动它,所以使用了以下代码
我正在处理线程。但是,当我尝试启动一个线程时,我得到一个异常。在具体的 java.lang.IllegalThreadStateException 中。我的代码是: public void readC
我正在对一个应用程序执行负载测试,并且有5个线程。我希望所有线程都可以随机运行,因此知道设备上的负载。假设运行所有线程的次数为5,则所有线程应成功运行5次而没有IllegalThreadStateEx
根据 中提到的错误,我们的应用每天会收到大约 1k 次崩溃。 OneSignal的 github issues . 错误说明: 不幸的是,我无法重现此问题。所有的崩溃都来自 Crashlytics 报
我收到 IllegalThreadStateException。 在 Eclipse 的调试器下一切正常,但当我尝试在 Firefox 上测试它时,它开始失败。第一次运行正常,刷新网页后出现异常。 这
需要制作一个音乐播放器作为我的简单java项目。它打开一个文件并将名称加载到文本字段中。当按下“播放”按钮时,该名称会在文本字段中圈出,当按下“暂停”按钮时,该圈圈会暂停。播放暂停是 JToggleb
错误消息是java.lang.IllegalThreadStateException(位于timeOutControl.start()行)。可能是什么原因? TimeOutControl timeOu
我有一个java程序,需要很长时间才能编译。 出于测试目的,如果编译需要很长时间,我想终止该程序并重新启动它。 这是我的代码的简化版本: public class Main { public
try { this.interrupt(); } catch (IllegalThreadStateException e) { e.printStackTrace(); } 我发现
只是来完善我的应用程序并使其在用户离开后恢复。当应用程序恢复时,我得到一个 IllegalThreadStateException,这很烦人。这个问题出现在谷歌给出的例子中 Lunar Lander
在 Java 中,我得到这个异常: Exception in thread "main" java.lang.IllegalThreadStateException at java.lang.
我的程序中有 2 个线程和一个主类,每当我尝试运行它时,一个线程就会给我一个 IllegalThreadStateException,我不知道为什么。程序需要进行一场龟兔赛跑,乌龟可以移动10米,直到
我是一名优秀的程序员,十分优秀!