如何根据Element属性从PriorityQueue中删除元素?

时间:2015-10-23 11:23:00

标签: java search priority-queue

我尝试在Maximum Waiting Time内设置PQueue。如果有Maximum Waiting Time等待PQueue以上的links将其删除,则此Maximum Waiting Time会自动检查我的PQueue。我对我的代码进行了这项更改,但它在删除链接后正好停止了。我想根据等待时间条件从我的public class MyClass { public static PriorityQueue <LinkNodeLight> PQueue = new PriorityQueue <> (); private static Set<String> DuplicationLinksHub = new LinkedHashSet <> (); private static Integer IntraLinkCount = new Integer (0); private static Integer InterLinkCount = new Integer (0); private static Integer DuplicationLinksCount = new Integer (0); private static Integer MaxWaitTime = new Integer (60000); // 1 M= 60000 MS @SuppressWarnings("null") LinkNode deque(){ LinkNode link = null; synchronized (PQueue) { link = (LinkNode) PQueue.poll(); if (link != null) { link.setDequeTime(new DateTime()); if (link.isInterLinks()) synchronized (InterLinkCount) { InterLinkCount--; } else synchronized (IntraLinkCount) { IntraLinkCount--; } } synchronized (PQueue) { if (link.waitingInQueue()>MaxWaitTime) { link = (LinkNode) PQueue.remove(); System.out.println("*********************************"); System.out.println("This Link is Deopped: " + link); System.out.println("%%% MaX Waiting Time:" + (MaxWaitTime/60000)+"Min"); System.out.println("*********************************"); } } return link; } 中删除所有元素。你能告诉我这里缺少什么吗?

这是我的班级:

public partial class WSDayBookReport : System.Web.UI.Page
{
    SQLClass sqlfunc = new SQLClass();
    DayBookDataSet dset = new DayBookDataSet();
    ReportDocument rdoc;
}
protected void Page_Load(object sender, EventArgs e)
{
}
protected void Page_Unload(object sender, EventArgs e)
{
    try
    {
        rdoc.Close();
        rdoc.Dispose();
        rdoc = null;
    }
    catch (Exception ex)
    {
    }
}
public void OpeningStock()
{
    string qry = "select  i.ItemGroupID, ig.ItemGroupCode As ItemGroupCode, Sum(iss.RegularStock) As OpeningStock from ItemStock iss, Item i, ItemGroup ig where ig.ItemGroupID = i.ItemGroupID AND iss.ItemID = i.ItemId group by i.ItemGroupID,ig.ItemGroupCode";
    sqlfunc.GetDataFromDT(dset.ItemGroupStock, qry, "sqlcon");
    var q1 = from igs in dset.ItemGroupStock.AsEnumerable()
             select igs;
    foreach (var res in q1)
    {
        res.ConsumedStock = 0;
        res.ClosingStock = 0;
    }
    dset.AcceptChanges();
    //Response.Write(dset.ItemGroupStock.Rows.Count.ToString() + "=Opening Stock");
}
public void loadUser()
{
    string qry = "select pp.PersonnelParticularID As UserID, pp.PersonnelName As UserName from WineOrder wo, WineOrderDetail wod, PersonnelParticular pp, ItemGroup ig, Item i where pp.PersonnelParticularID = wo.IssuedToPersonnelID AND ig.ItemGroupID = i.ItemGroupID AND i.ItemID = wod.ItemID AND wod.IsOrderCancelled = 0 AND wod.WineOrderId = wo.WineOrderId AND wo.WineOrderDate ='" + Convert.ToDateTime(txtDate.Text).ToString("MM/dd/yyyy") + "' group by pp.PersonnelParticularID,pp.PersonnelName";
    sqlfunc.GetDataFromDT(dset.UserMaster, qry, "sqlcon");
    qry = "select  pp.PersonnelParticularID As UserID,ig.ItemGroupID, sum(wod.OrderQty) As ConsumptionQty from WineOrder wo, WineOrderDetail wod, ItemGroup ig, Item i, PersonnelParticular pp where pp.PersonnelParticularID = wo.IssuedToPersonnelID AND ig.ItemGroupID = i.ItemGroupID AND i.ItemID = wod.ItemID AND wod.IsOrderCancelled = 0 AND wod.WineOrderId = wo.WineOrderId AND wo.WineOrderDate='" + Convert.ToDateTime(txtDate.Text).ToString("MM/dd/yyyy") + "' group by ig.ItemGroupID, pp.PersonnelParticularID";
    sqlfunc.GetDataFromDT(dset.UserConsume, qry, "sqlcon");
}
protected void btnSubmit_Click(object sender, EventArgs e)
{
    dset = new DayBookDataSet();
    OpeningStock();
    loadUser();
    //Deducting new RU Entry after the entered date...
    DataTable dtTemp = new DataTable();
    string qry2 = "select Sum(rs.Quantity) As Qty,i.ItemGroupID from RegularStock rs, Item i where i.ItemID = rs.ItemID AND rs.RSDate>='" + Convert.ToDateTime(txtDate.Text).ToString("MM/dd/yyyy") + "' Group by i.ItemGroupID";
    sqlfunc.GetDataFromDT(dtTemp, qry2, "sqlcon");
    if (dtTemp.Rows.Count > 0)
    {
        for (int i = 0; i < dtTemp.Rows.Count; i++)
        {
            var q5 = from igs in dset.ItemGroupStock.AsEnumerable()
                     where igs.ItemGroupID == Convert.ToInt32(dtTemp.Rows[i][1].ToString())
                     select igs;
            foreach (var res in q5)
            {
                res.OpeningStock -= Convert.ToDecimal(dtTemp.Rows[i][0].ToString());
            }
        }
    }
    //Adding cosumed stock from the entered date.
    dtTemp = new DataTable();
    string qry = "select  ig.ItemGroupID, sum(wod.OrderQty) As ConsumptionQty from WineOrder wo, WineOrderDetail wod, ItemGroup ig, Item i where ig.ItemGroupID = i.ItemGroupID AND i.ItemID = wod.ItemID AND wo.IssuedToPersonnelID is not null AND wod.IsOrderCancelled = 0 AND wod.WineOrderId = wo.WineOrderId AND wo.WineOrderDate>='10-01-2015' group by ig.ItemGroupID";
    sqlfunc.GetDataFromDT(dtTemp, qry, "sqlcon");
    if (dtTemp.Rows.Count > 0)
    {
        for (int i = 0; i < dtTemp.Rows.Count; i++)
        {
            var q5 = from igs in dset.ItemGroupStock.AsEnumerable()
                     where igs.ItemGroupID == Convert.ToInt32(dtTemp.Rows[i][0].ToString())
                     select igs;
            foreach (var res in q5)
            {
                res.OpeningStock += Convert.ToDecimal(dtTemp.Rows[i][1].ToString());
            }
        }
    }
    dset.AcceptChanges();
    var qry10 = from us in dset.UserConsume.AsEnumerable()
                group us by us.ItemGroupID into g
                select new
                {
                    TOTAL = g.Sum(x => x.ConsumptionQty),
                    IG = g.Key
                };
    foreach (var res in qry10)
    {
        //Response.Write(res.IG.ToString() +"-"+res.TOTAL.ToString()+ "----------");
        var qrry = from igs in dset.ItemGroupStock.AsEnumerable()
                   where igs.ItemGroupID == res.IG
                   select igs;
        foreach (var res2 in qrry)
        {
            res2.ClosingStock = res2.OpeningStock - res.TOTAL;
        }
    }
    rdoc = new ReportDocument();
    rdoc.Load(Server.MapPath("~/Report/WSDayBookRpt.rpt"));
    rdoc.SetDataSource(dset);
    CrystalReportViewer1.DataBind();
    CrystalReportViewer1.ReportSource = rdoc;
    CrystalReportViewer1.RefreshReport();
}
}

1 个答案:

答案 0 :(得分:3)

您的问题有点不透明,但如果我理解正确,您需要检查PriorityQueue以查看是否有等待时间超过特定时间的项目。

正如已经提到的那样,您对synchronizedIntraLinkCountInterLinkCount的使用有点奇怪。有一个相当未知的替代方法,原子整数类AtomicInteger(在包java.util.concurrent.atomic中:

private static AtomicInteger IntraLinkCount = Integer.valueOf(0);

这将按您的意愿工作。

第二个问题是您使用poll()方法。这将从队列中删除顶部项目。也许您想要使用peek(),如果返回的链接对象满足remove(),则只使用link.waitingInQueue() > MaxWaitTime

顺便说一句,你的队列将根据他们的“自然顺序”返回项目。这意味着使用compareTo方法,并且首先从队列返回“最小”。我想您可能希望实现一个自定义compareTo,将等待时间最长的链接放在首位?

您也可以create your PriorityQueue with a custom Comparator反对。

这样的事情:

public class MyClass {
    public static PriorityQueue<LinkNodeLight> PQueue = new PriorityQueue<>();

    private static AtomicInteger IntraLinkCount = new AtomicInteger(0);
    private static AtomicInteger InterLinkCount = new AtomicInteger(0);

    private static Integer MaxWaitTime = Integer.valueOf(60_000); // 1 M= 60000 MS

    LinkNode deque() {
        LinkNode link = null;

        synchronized (PQueue) {
            link = PQueue.peek();

            if (link != null) {
                link.setDequeTime(LocalDateTime.now());

                if (link.isInterLinks())
                    InterLinkCount.decrementAndGet();
                else
                    IntraLinkCount.decrementAndGet();

                if (link.waitingInQueue() > MaxWaitTime) {
                    link = PQueue.remove();

                    System.out.println("*********************************");
                    System.out.println("This Link is Deopped: " + link);
                    System.out.println("%%% MaX Waiting Time:" + MaxWaitTime / 60000 + "Min");
                    System.out.println("*********************************");

                    return link;
                } else
                    return null;
            }
        }

        return link; // Not sure what you want to return here
    }
}

如果你有幸参与Java 8,那么这样的一些魔术可能会有用:

synchronized (PQueue) {
    link = PQueue.stream().filter(node -> node.waitingInQueue() > MaxWaitTime).findFirst().orElse(null);

    if (link != null)
        PQueue.remove(link);
}