java - 有没有办法让多个线程顺序访问共享资源列表?

标签 java multithreading

有没有办法让多个线程顺序访问共享资源列表,我有两个线程 t1 和 t2,我想根据条件访问对象列表,而且我希望每个线程之前只处理一次允许其他线程。

类项目(int itemid,String itemname,int 优先级)

示例输入:

[ 123,"item1", 8 ], [124, "item2", 2], [125, "item3", 5 ], [126,"item4", 3]

预期输出:

Thread1: Processing Item - 123, priority - 8,
Thread2: Processing Item - 125, priority - 5,
Thread1: Processing Item - 126, priority - 3,
Thread2: Processing Item - 124, priority - 2,

尝试使用具有同步功能的优先级队列,但无法按顺序访问对象列表。

public class Items implements Comparable<Items>{
private int itemID;
private String itemname;
private int priority;

public Items(int itemID, String itemname, int priority)
{
    this.itemID = itemID;
    this.itemname = itemname;
    this.priority = priority;
}
public int getItemID() {
    return itemID;
}


public void setItemID(int itemID) {
    this.itemID = itemID;
}


public String getItemname() {
    return itemname;
}


public void setItemname(String itemname) {
    this.itemname = itemname;
}


public int getPriority() {
    return priority;
}


public void setPriority(int priority) {
    this.priority = priority;
}


@Override
public int compareTo(Items item) {

    return item.priority > this.priority ? 1 : item.priority < this.priority ? -1 :0;
}

}
package multithreading;

import java.util.concurrent.PriorityBlockingQueue;

public class itemsImpl {

    private static PriorityBlockingQueue<Items> priorityQueue;

    public static void main(String[] args)
    {
        priorityQueue = new PriorityBlockingQueue<Items>();

        priorityQueue.add(new Items( 123,"item1", 8));
        priorityQueue.add(new Items( 124, "item2", 2));
        priorityQueue.add(new Items( 125, "item3", 5));
        priorityQueue.add(new Items( 126,"item4", 3));

        itemsImpl impl = new itemsImpl();

        Thread t1 = new Thread( new Runnable(){
        public void run()
        {
            try {
                impl.pollQueue(Thread.currentThread().getName());
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }});

        Thread t2 = new Thread( () -> {
            try {
                impl.pollQueue(Thread.currentThread().getName());
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        } );
        t1.start();
        t2.start();
        }


    private void pollQueue(String name) throws InterruptedException
    {   
        while(priorityQueue.size()>0)
        {
            synchronized(this)
            {   
                    Items i = priorityQueue.poll();
                    System.out.println(name +": Items Processsing - " + i.getItemID() + ", priority - " + i.getPriority());
                    Thread.sleep(100);
            }

        }


    }

}

最佳答案

您需要添加一个标志来定义哪个线程应该处理下一个项目。

public class itemsImpl {

    private static PriorityBlockingQueue<Items> priorityQueue;
    private volatile boolean flag = false; //flag to define which thread should proceed

    public static void main(String[] args) {
        priorityQueue = new PriorityBlockingQueue<Items>();

        priorityQueue.add(new Items( 123,"item1", 8));
        priorityQueue.add(new Items( 124, "item2", 2));
        priorityQueue.add(new Items( 125, "item3", 5));
        priorityQueue.add(new Items( 126,"item4", 3));

        itemsImpl impl = new itemsImpl();

        Thread t1 = new Thread( new Runnable(){
            public void run() {
                try {
                    impl.pollQueue(Thread.currentThread().getName(), false);
                } catch (InterruptedException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
        }});

        Thread t2 = new Thread( () -> {
            try {
                impl.pollQueue(Thread.currentThread().getName(), true);
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        } );
        t1.start();
        t2.start();
    }


    private void pollQueue(String name, boolean expected) throws InterruptedException {
        while(priorityQueue.size()>0) {
            synchronized(this) {
                while (flag != expected) { // thread is waiting for its turn
                    this.wait();
                }
                Items i = priorityQueue.take(); //You need to either use blocking take() or check that item is not null
                System.out.println(name +": Items Processsing - " + i.getItemID() + ", priority - " + i.getPriority());
                flag = !expected;
                this.notifyAll();
            }
        }
    }
}

关于java - 有没有办法让多个线程顺序访问共享资源列表?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57583840/

相关文章:

java - 如何在 Java 的枚举中保存图像?

c# Task.WhenAll 在等待完成时阻塞

c# - Interlocked 是否保证对 C# 中其他线程的可见性,还是我仍然必须使用 volatile?

java - Guavas Futures.transform 的 Spring 实现

java - 无法使用 Intent 获取传递的值

java - Android Studio - 权限拒绝,需要 android.permission.RECEIVE_SMS 错误

javascript - JavaScript 中的自定义计时器

java - 如何在 Java 中比较字符串?

java - 等待另一个线程中的邮件发送完成

multithreading - 在Apple的Cocoa API中,为什么从主线程调用NSApplicationMain很重要?