java - 有线程和无线程的并发

标签 java concurrency derby

我有一个需要用户登录的应用程序。数据存储在 Derby DB 中。下面的表单根据用户名和密码字段进行查询,并设置一个用户 session ,该 session 应填充用户数据。

但是,即使数据库正在对用户进行身份验证, session 也会返回 null。如何将 system.out.println 放入此类的 main 方法中,该方法将根据数据库查询返回 session 数据,而不是立即执行代码并返回 null?

注意:数据库工作正常。我可以根据 sql 语句中的用户名和密码字段获取结果。

public class LoginForm{

    private static JTextField userName;
    private static JTextField password;
    private static JButton submit;
    private static int attempts;
    private static JFrame main;

    private Dimension dim = Toolkit.getDefaultToolkit().getScreenSize();

    final int MAX_ATTEMPTS = 5;

    private UserSession session;

    public LoginForm(){

        Handler handle = new Handler();                             //inner class
        LoginFormFocusListener fl = new LoginFormFocusListener();   //inner class

        main = new JFrame();

        main.setUndecorated(true);
        main.setBounds((dim.width/2) - (500/2),(dim.height/2) - (150/2),500, 75);
        main.setVisible(true);
        main.setAlwaysOnTop(true);
        main.setResizable(false);
        main.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        userName = new JTextField(10);
        password = new JTextField(10);
        main.setLayout(new GridLayout(0,1));

        JPanel panel = new JPanel();
        main.add(panel);

        panel.add(new JLabel("Username: "));
        panel.add(userName);
        panel.add(new JLabel("Password: "));
        panel.add(password);
        panel.setBorder(BorderFactory.createTitledBorder(BorderFactory.createBevelBorder(4), "Please Login"));

        submit = new JButton("Submit");
        panel.add(submit);

        if(attempts > 0){
            panel.add(new JLabel("" + (MAX_ATTEMPTS - attempts) + " attempts remaining..."));
        }

        main.addWindowFocusListener(fl);
        submit.addActionListener(handle);
    }



    public UserSession getSession(){
        return this.session;
    }

    /**
     * creates the session that's returned to main/POSsystem via getSession
     * @author Matt
     *
     */
    private class Handler implements ActionListener
    {
        @Override
        public void actionPerformed(ActionEvent e) {
            String user = userName.getText();
            String pass = password.getText();

            session = new UserSession();
            if(session.authenticate(user,  pass)){
                System.out.println("User has been authenticated");
                JOptionPane.showMessageDialog(null,"Login Successful! ","",JOptionPane.PLAIN_MESSAGE);
            }else{
                System.out.println("Login Failed!");
                JOptionPane.showMessageDialog(null,"Login Failed!","", JOptionPane.WARNING_MESSAGE);
                attempts++;
                if(attempts < MAX_ATTEMPTS){
                    new LoginForm();
                }else{
                    JOptionPane.showMessageDialog(null, "Max attempts reached.  " +
                                                        "Please Contact the administrator of this system. ",
                                                        "User Locked",
                                                        JOptionPane.ERROR_MESSAGE);
                }
            }
        }
    }

    /**
     * Inner Class
     * custom focus events for the login form
     * the user may click away from this pop-up to close it.
     * @author Matt
     *
     */
    public class LoginFormFocusListener implements WindowFocusListener{

        @Override
        public void windowGainedFocus(WindowEvent wEvt) {}

        @Override
        public void windowLostFocus(WindowEvent wEvt) {
            ((JFrame) wEvt.getSource()).dispose();
        } 
    }    

    //test
    public static void main(String args[]){

        SwingUtilities.invokeLater(new Runnable(){  
              public void run(){  
                LoginForm lf = new LoginForm();  
                System.out.println("Session: " + lf.getSession());    <---NULL!!!
              }  
            });  


    }

}

最佳答案

如果您真正想要的是将输出发送到控制台,则不应将 System.out.println 代码放在 main 方法中,而应将其放置在 actionPerformed 方法的最后一行。

如果您真的非常非常希望在 main 方法中包含该代码,那么您应该创建一个实现 Runnable 接口(interface)的类,该类允许获取创建的 LoginForm

像这样:

final class InitThread implements Runnable {
LoginForm lf;

public LoginForm getLfForSystemOut() {
    while (lf == null) {
        try {
            Thread.sleep(500);
        } catch (final InterruptedException e) {
            return null;
        }
    }
    synchronized (lf) {
        try {
            lf.wait();
            return lf;
        } catch (final InterruptedException e) {
            e.printStackTrace();
        }
    }
    return null;
}

@Override
public void run() {
    lf = new LoginForm();
}
}

然后将 main 方法更改为:

public static void main(final String args[]) {

    final InitThread init = new InitThread();
    SwingUtilities.invokeLater(init);

    System.out.println("Session: " + init.getLfForSystemOut().getSession());

}

最后在该 block 的 actionPerformed 方法的末尾:

synchronized (LoginForm.this) {
    LoginForm.this.notifyAll();
}

关于java - 有线程和无线程的并发,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12254318/

相关文章:

java - 停止java.util.concurrent.Executor任务的方法

string - 字符串的不变性和并发性

java - 使用哪些 jar 文件来实现 JFreeChart 应用程序?

java - 在 Java 中开发高度可扩展的 Web 应用程序需要做什么?

c# - 为什么Task Parallel Library在某些情况下调度任务会出现 'hidden' 1秒超时?

database - db derby StartNetworkServer

java - 从查询更新 JTable

java - 为 Derby DB 使用 PreparedStatement 时出现 SQLException

java - 在 ClassLoader 上调用 `defineClass` 会导致 "No matching method found"

java - 保存 EditText 并自动检索