繁体   English   中英

java 中的链表队列不适用于线程

[英]linkedlist Queue in java not working with threads

这是我用来实现队列的代码。 这里队列轮询总是返回 null 即使队列不为空。

Runnable runnable = new Runnable() {

    @Override
    public void run() {
        service.schedule(runnable, 500, TimeUnit.MILLISECONDS);
        process();
    }

    public void process() {
        try {
            String tt = nextItem();
            //System.out.println("SQ:"+tt);
        } catch (Exception e) {//Catch exception if any
            System.out.println("2Error: " + e.getMessage());
        }
    }
};

public String nextItem() {
    Object poll;
    try {
        synchronized (queue) {
            System.out.println("SQ:" + queue.poll());
            //if (poll != null) {
            //    return poll.toString();
            //} else {
            return "";
            //}
        }
    } catch (Exception e) {
        e.printStackTrace();
        return "";
    }
}

public void run() {
    try {
        Class.forName("com.mysql.jdbc.Driver");
        String url =
                "jdbc:mysql://1xxx:3306/ayan";
        Connection con =
                DriverManager.getConnection(
                url, "[user]", "[pass]");

        Queue queue = new LinkedList();
        service = Executors.newScheduledThreadPool(1000);
        service.schedule(runnable, 0, TimeUnit.MILLISECONDS);
        while (true) {
            Statement statement = con.createStatement();
            statement.setFetchSize(1);
            ResultSet resultSet = statement.executeQuery("SELECT * from query_q");
            while (resultSet.next()) {
                // process results. each call to next() should fetch the next row
                String id = resultSet.getString("id");
                String query = resultSet.getString("query");
                String msisdn = resultSet.getString("msisdn");
                String pass = id + "|" + query + "|" + msisdn;
                System.out.println("MQ:" + pass);
                //String str = "foo";
                //Queue<Character> charsQueue = new LinkedList<Character>();
                boolean inserted = false;
                for (char c : pass.toCharArray()) {
                    inserted = queue.offer(c);
                }

                if (inserted != false) {
                    // Statement stats = con.createStatement();
                    //stats.executeUpdate("delete from query_q where id=" + id);
                }
            }
            Thread.sleep(10000);
        }
        //con.close();
}

LinkedList 是唯一的非线程安全队列。 任何其他实现将是一个更好的选择。 您的报价未同步。 ;)

ExecutorService 有一个内置队列。 您可以利用它而根本不创建自己的队列。 只需执行(可运行)任务,因为您需要做一些事情。

那是因为您没有为 queue.offer() 同步队列。 您需要同步对队列的所有访问。

最简单的方法是使用LinkedBlockingQueue ,它将为您处理所有同步。

请注意,您在不同的queue上调用offer()poll() - offer()queue是一个局部变量,而poll()的一个可能是一个字段:

Queue queue = new LinkedList(); 

此外,正如其他答案中所建议的那样,需要同步。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM