Связанный список очереди в Java не работает с потоками - PullRequest
0 голосов
/ 03 мая 2011

Это код, который я использую для реализации очереди.Здесь опрос очереди всегда возвращает ноль, даже если очередь не пуста.

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();
}

Ответы [ 3 ]

1 голос
/ 03 мая 2011

LinkedList - единственная не поточно-безопасная очередь. Любая другая реализация была бы лучшим выбором. Ваше предложение не синхронизировано. ;)

ExecutorService имеет встроенную очередь. Вы можете использовать это и вообще не создавать свою собственную очередь. Просто выполняйте (Runnable) задачи, когда вам нужно что-то сделать.

0 голосов
/ 03 мая 2011

Обратите внимание, что вы вызываете offer() и poll() для разных queue - offer() * queue - это локальная переменная, тогда как poll() - это, вероятно, поле:

Queue queue = new LinkedList(); 

Кроме того, требуется синхронизация, как предлагается в других ответах.

0 голосов
/ 03 мая 2011

Это потому, что вы не синхронизируете очередь для вашего queue.offer ().Вам необходимо синхронизировать весь доступ к очереди.

Самый простой способ сделать это - использовать LinkedBlockingQueue , который позаботится обо всей синхронизации для вас.

...