在java中,只有一个线程在遍历ArrayList

在java中,只有一个线程在遍历ArrayList,java,multithreading,thread-synchronization,Java,Multithreading,Thread Synchronization,我在下面写了一段代码,其中有一个Employee对象列表,其中有三个属性employeeId、employeeName和salary。我正在使用两个线程迭代该列表,并将salary递增100。但是,当这个代码只执行一个线程正在执行作业时,意味着只有一个线程,即“t1”正在执行增量,而另一个线程根本不执行任何操作。我如何实现所有线程读取员工列表并执行增量工资属性 public class MultipleThreadsReadingFromFile { public static voi

我在下面写了一段代码,其中有一个Employee对象列表,其中有三个属性employeeId、employeeName和salary。我正在使用两个线程迭代该列表,并将salary递增100。但是,当这个代码只执行一个线程正在执行作业时,意味着只有一个线程,即“t1”正在执行增量,而另一个线程根本不执行任何操作。我如何实现所有线程读取员工列表并执行增量工资属性

public class MultipleThreadsReadingFromFile {

    public static void main(String[] args) throws InterruptedException {
        Employee e1 = new Employee(1, "zoheb", 10000);
        Employee e2 = new Employee(2, "anushka", 12000);
        Employee e3 = new Employee(3, "katrina", 15000);
        Employee e4 = new Employee(4, "kareena", 17000);
        Employee e5 = new Employee(5, "priety", 19000);
        Employee e6 = new Employee(6, "rani", 21000);
        Employee e7 = new Employee(7, "sunney", 23000);
        Employee e8 = new Employee(8, "soha", 23000);
        Employee e9 = new Employee(9, "allia", 29000);
        Employee e10 = new Employee(10, "asin", 30000);
        List<Employee> list = new ArrayList<Employee>();
        list.add(e1);
        list.add(e2);
        list.add(e3);
        list.add(e4);
        list.add(e5);
        list.add(e6);
        list.add(e7);
        list.add(e8);
        list.add(e9);
        list.add(e10);
        ListThread run = new ListThread(list);
        Thread t1 = new Thread(run, "t1");
        Thread t2 = new Thread(run, "t2");
        t1.start();
        t2.start();
        t1.join();
        t2.join();
        System.out.println("main over");
    }
}

将相同的
Runnable
传递给两个线程,并在
Runnable
的构造函数中创建一个
迭代器,而不是在
run()
方法中,这意味着两个Runnable将“竞争”相同的列表(每个元素只由一个线程处理)。然而,这可能是你想要的

由于列表非常小(10个元素),线程
t1
可能有时间在线程
t2
完全启动之前处理所有元素,然后对于t2
itr.hasNext()
返回false,t2完成

编辑: 您还保留一个锁,因此您强制线程
t2
等待
t1
完成。 考虑使用A并从您的代码> Runnaby<代码>中删除锁(假设您的示例显示了列表的内容是静态的):

public类MultipleThreadsReadingFromFile{
公共静态void main(字符串[]args)引发InterruptedException{
员工e1=新员工(1,“zoheb”,10000);
雇员e2=新雇员(2,“anushka”,12000);
雇员e3=新雇员(3,“卡特里娜”,15000);
雇员e4=新雇员(4,“卡里娜”,17000);
员工e5=新员工(5,“priety”,19000);
雇员e6=新雇员(6,“rani”,21000);
员工e7=新员工(7,“桑尼”,23000);
员工e8=新员工(8,“soha”,23000);
员工e9=新员工(9,“allia”,29000);
员工e10=新员工(10,“asin”,30000);
BlockingQueue=new ArrayBlockingQueue(10);
添加(e1);
添加(e2);
添加(e3);
添加(e4);
添加(e5);
添加(e6);
queue.add(e7);
queue.add(e8);
queue.add(e9);
添加(e10);
ListThread run=新的ListThread(队列);
线程t1=新线程(运行“t1”);
螺纹t2=新螺纹(螺纹,“t2”);
t1.start();
t2.start();
t1.join();
t2.连接();
系统输出打印LN(“主输出”);
}
}
类ListThread实现Runnable{
封锁排队的员工;
公共ListThread(阻止队列员工){
这是。雇员=雇员;
}
@凌驾
公开募捐{
雇员e1;
而((e1=this.employees.poll())!=null){
System.out.println(Thread.currentThread().getName())
+“变更前”+e1);
双薪=e1.getSalary();
双倍加薪=((5/100)*工资);
工资=工资+100;
//系统输出打印项次(增量);
e1.固定工资(工资);
System.out.println(Thread.currentThread().getName())
+“变更后”+e1);
试一试{
睡眠(5000);
}捕捉(中断异常e){
//TODO自动生成的捕捉块
e、 printStackTrace();
}
}
}
}

arrayList不是线程安全的,你是在问如何让多个线程从列表中读/写吗?你的线程在释放锁之前要休眠5秒有什么原因吗?你应该稍微改进一下格式。几乎看不到开始和结束的位置…要使您的
ArrayList
线程安全,请使用
Collections.synchronizedList()
。是的,我希望有多个线程从同一个列表中读取,该列表是一个员工对象列表,对该对象执行写入操作,并将同一个员工对象放回列表中,但在这种情况下,一个线程正在执行任务,我已启动了两个线程,我希望两个线程都应该执行该任务
class ListThread implements Runnable {
    List<Employee> list;
    Iterator<Employee> itr = null;
    Lock lock = null;
    Employee e1=null;

    public ListThread(List<Employee> list) {
        super();
        this.list = list;
        this.itr=list.iterator();
        lock = new ReentrantLock();
    }

    @Override
    public void run() {
        while (true) {

            //synchronized (itr) {
            try{
            lock.lock();
                if (!itr.hasNext()) {
                    break;
                }
                e1 = itr.next();
                System.out.println(Thread.currentThread().getName()
                        + " Before change " + e1);
                double salary = e1.getSalary();
                double increment = ((5 / 100) * salary);
                salary = salary + 100;
                // System.out.println(increment);
                e1.setSalary(salary);
                System.out.println(Thread.currentThread().getName()
                        + " After change " + e1);
                try {
                    Thread.sleep(5000);
                } catch (InterruptedException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            //}
            }finally{
                lock.unlock();
            }
        }
    }
}
class Employee {
    int employeeId;
    String employeeName;
    double salary;

    public Employee(int employeeId, String employeeName, double salary) {
        super();
        this.employeeId = employeeId;
        this.employeeName = employeeName;
        this.salary = salary;
    }

    public int getEmployeeId() {
        return employeeId;
    }

    public void setEmployeeId(int employeeId) {
        this.employeeId = employeeId;
    }

    public String getEmployeeName() {
        return employeeName;
    }

    public void setEmployeeName(String employeeName) {
        this.employeeName = employeeName;
    }

    public double getSalary() {
        return salary;
    }

    public void setSalary(double salary) {
        this.salary = salary;
    }

    @Override
    public String toString() {
        return "Employee [employeeId=" + employeeId + ", employeeName="
                + employeeName + ", salary=" + salary + "]";
    }
}
public class MultipleThreadsReadingFromFile {

    public static void main(String[] args) throws InterruptedException {
        Employee e1 = new Employee(1, "zoheb", 10000);
        Employee e2 = new Employee(2, "anushka", 12000);
        Employee e3 = new Employee(3, "katrina", 15000);
        Employee e4 = new Employee(4, "kareena", 17000);
        Employee e5 = new Employee(5, "priety", 19000);
        Employee e6 = new Employee(6, "rani", 21000);
        Employee e7 = new Employee(7, "sunney", 23000);
        Employee e8 = new Employee(8, "soha", 23000);
        Employee e9 = new Employee(9, "allia", 29000);
        Employee e10 = new Employee(10, "asin", 30000);
        BlockingQueue<Employee> queue = new ArrayBlockingQueue<Employee>(10);
        queue.add(e1);
        queue.add(e2);
        queue.add(e3);
        queue.add(e4);
        queue.add(e5);
        queue.add(e6);
        queue.add(e7);
        queue.add(e8);
        queue.add(e9);
        queue.add(e10);
        ListThread run = new ListThread(queue);
        Thread t1 = new Thread(run, "t1");
        Thread t2 = new Thread(run, "t2");
        t1.start();
        t2.start();
        t1.join();
        t2.join();
        System.out.println("main over");
    }
}


class ListThread implements Runnable {

    BlockingQueue<Employee> employees;

    public ListThread(BlockingQueue<Employee> employees) {
        this.employees = employees;
    }

    @Override
    public void run() {
        Employee e1;
        while ((e1 = this.employees.poll()) != null) {

            System.out.println(Thread.currentThread().getName()
                    + " Before change " + e1);
            double salary = e1.getSalary();
            double increment = ((5 / 100) * salary);
            salary = salary + 100;
            // System.out.println(increment);
            e1.setSalary(salary);
            System.out.println(Thread.currentThread().getName()
                    + " After change " + e1);
            try {
                Thread.sleep(5000);
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
    }
}