多线程同步问题

问题:定时任务获取一个列表list,该list数据有增有减,有两个线程需要遍历该list,得到每个实例数据,代码如下,问题是对list加上volatile或者修改list为Collections.synchronizedList,代码无异常,下面的代码有哪些bug呢

代码:

import java.util.*;
public class TestList {
	static List<Integer> list = new ArrayList<>();
	static Random rand = new Random(47);
	static class Task extends TimerTask {
		public void run() {
			synchronized (list) {
				System.out.println("timer");
				list.clear();
				int n = rand.nextInt(100);
				for (int i = 0; i < n; i++) {
					list.add(i);
				}
			}
		}
	}
	static class MyThread extends Thread {
		MyThread(String name) { super(name); }
		public void run() {
			while (true) {
				for (int i = 0, n = list.size(); i < n; i++) {
					synchronized (list) {
						if (i < list.size()) {
							System.out.println(getName() + "," + list.get(i));
						} else {
							break;
						}
					}
				}
			}			
		}
	}
	public static void main(String[] args) {
		MyThread t1 = new MyThread("t1");
		MyThread t2 = new MyThread("t2");
		t1.start();
		t2.start();
		Task task = new Task();
		Timer timer = new Timer();
		timer.schedule(task, 0, 30);
	}
}

评论区

JFinal

2019-09-26 22:34

“问题是无异常” 这是什么意思?

dapk

2019-09-27 20:44

@JFinal “无异常”是指t1和t2可以取到list中的数据,并打印出来,不会发生处于runnable状态而取不到list中数的情况

JFinal

2019-09-27 20:48

@dapk 你在 list 上使用了 synchronized 当然就没异常了

你将 for (int i = 0, n = list.size(); i < n; i++) 这个循环改成 for ( Iterator it=list.iterator(); it.hasNext();) 就会有异常了,注意要是大并发下面有异常

dapk

2019-09-27 21:03

@JFinal 项目中list保存的是规则列表(存在mysql中,有更新,但不频繁,且数量不多),现在的情况是系统被动接受数据(8个线程,1000个/s),根据规则列表的规则,给接受的数据打标签0,1,请问该怎么啊

热门反馈

扫码入社