简体   繁体   中英

linkedlist Queue in java not working with threads

This is the code that I am using to implement the queue. Here queue poll is always returning null even when queue is not empty.

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 is the only non-thread safe Queue. Any other implementation would have been a better choice. Your offer is not synchronized. ;)

An ExecutorService has a built in queue. You can make use of that and not create a queue of your own at all. Just execute(Runnable) tasks as you need something to be done.

That's because you are not synchronizing the queue for your queue.offer(). You need to synchronize all access to the queue.

The simplest way to do this is to use a LinkedBlockingQueue which will take care of all the synchronization for you.

Note that you call offer() and poll() on different queue 's - offer() 's queue is a local variable, whereas the poll() 's one is probably a field:

Queue queue = new LinkedList(); 

Also, syncrhonization is required, as suggested in other answers.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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