关于java多线程的小疑点
关于java多线程的小问题
我写了个测试类:
public class Test extends Thread {
private String st ;
private static List<String> list = new ArrayList<String>();
public Test(int i){
st = "str"+i;
}
public static void main(String[] args) throws Exception {
String[] arr = new String[10];
for(int i=0 ; i<arr.length;i++){
arr[i] = "str"+i;
list.add(arr[i]);
}
for(int i=0 ; i<arr.length;i++){
Test test = new Test(i);
test.start();
}
while(true){
if(list.isEmpty()){
break;
}
}
System.out.println("finished");
}
public void run() {
for(int i = 0;i<list.size();i++){
if(st.equals(list.get(i))){
list.remove(i);
}
}
System.out.println(st);
}
}
运行的时候发现代码一直停留在while(true){
if(list.isEmpty()){
break;
}
}
正常逻辑应该是所有线程运行完之后要打印"finished".
另外帮忙看下会不会出现多个线程操作同一个对象的情况?要不要加锁?
------解决思路----------------------
个人的一点浅见:
应该是 循环中remove导致的
例子 :比如 线程1对应的值索引是4 线程2对应的索引是9(list最后一个)
当线程2 循环到i=9时,线程1正好remove,导致i>list.size ,跳出循环,线程2对应的值永远也移除不了
但是在楼主的这个例子中,runfang方法执行比较简单,通过for循环串行的开启多线程,机器性能好的话和同步执行10次区别不大,第二个线程开启所消耗的时间第一个线程的run方法都可能已经执行完了
楼主把run方法 syso的函数放到if(st.equals(list.get(i)))中你会发现凡是卡住的情况,输出都不完整,而写道if外边,无论是否移出都会执行的,输出意义不大 !
------解决思路----------------------
改造了下
------解决思路----------------------
for(int i = 0;i<list.size();i++){
if(st.equals(list.get(i))){
list.remove(i);
}
这段代码单线程都有问题,更别说多线程了
退一万步讲,还是没问题的话
多线程进来就一定是按照线程0、线程1、线程2....顺序执行吗
如果不是,那么只要有一个线程执行的时候不是按照进来的顺序执行,那个判断就不成立,就删不掉(前提是不跑异常),那么list就不会为empty
我写了个测试类:
public class Test extends Thread {
private String st ;
private static List<String> list = new ArrayList<String>();
public Test(int i){
st = "str"+i;
}
public static void main(String[] args) throws Exception {
String[] arr = new String[10];
for(int i=0 ; i<arr.length;i++){
arr[i] = "str"+i;
list.add(arr[i]);
}
for(int i=0 ; i<arr.length;i++){
Test test = new Test(i);
test.start();
}
while(true){
if(list.isEmpty()){
break;
}
}
System.out.println("finished");
}
public void run() {
for(int i = 0;i<list.size();i++){
if(st.equals(list.get(i))){
list.remove(i);
}
}
System.out.println(st);
}
}
运行的时候发现代码一直停留在while(true){
if(list.isEmpty()){
break;
}
}
正常逻辑应该是所有线程运行完之后要打印"finished".
另外帮忙看下会不会出现多个线程操作同一个对象的情况?要不要加锁?
------解决思路----------------------
个人的一点浅见:
应该是 循环中remove导致的
例子 :比如 线程1对应的值索引是4 线程2对应的索引是9(list最后一个)
当线程2 循环到i=9时,线程1正好remove,导致i>list.size ,跳出循环,线程2对应的值永远也移除不了
但是在楼主的这个例子中,runfang方法执行比较简单,通过for循环串行的开启多线程,机器性能好的话和同步执行10次区别不大,第二个线程开启所消耗的时间第一个线程的run方法都可能已经执行完了
楼主把run方法 syso的函数放到if(st.equals(list.get(i)))中你会发现凡是卡住的情况,输出都不完整,而写道if外边,无论是否移出都会执行的,输出意义不大 !
------解决思路----------------------
改造了下
public class Test extends Thread {
private String st;
private static List<String> list = new ArrayList<String>();
public Test(int i) {
st = "str" + i;
}
public static void main(String[] args) throws Exception {
String[] arr = new String[10];
for (int i = 0; i < arr.length; i++) {
arr[i] = "str" + i;
list.add(arr[i]);
}
for (int i = 0; i < arr.length; i++) {
Test test = new Test(i);
test.start();
}
while (true) {
if (list.isEmpty()) {
break;
}
sleep(500);
}
System.out.println("finished");
}
public void run() {
removeStr(st);
System.out.println(st);
}
public synchronized static void removeStr(String str) {
Iterator<String> it = list.iterator();
while (it.hasNext()) {
String strTemp = it.next();
if (strTemp.equals(str)) {
it.remove();
break;
}
}
}
public synchronized static boolean isEmpty() {
return list.isEmpty();
}
}
------解决思路----------------------
for(int i = 0;i<list.size();i++){
if(st.equals(list.get(i))){
list.remove(i);
}
这段代码单线程都有问题,更别说多线程了
退一万步讲,还是没问题的话
多线程进来就一定是按照线程0、线程1、线程2....顺序执行吗
如果不是,那么只要有一个线程执行的时候不是按照进来的顺序执行,那个判断就不成立,就删不掉(前提是不跑异常),那么list就不会为empty