synchronized方法不能同步

时间:2017-06-05 15:38:08

标签: java synchronization

我必须创建多个客户端线程,每个都必须登录。我已经将user_login函数实现为synchronized,但是当我在线程的run方法中调用它时,多个线程同时访问它。我只想要一个客户端应先登录然后再登录,依此类推......

import java.io.*;
import java.rmi.NotBoundException;
import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;
import java.util.Scanner;
import java.util.logging.FileHandler;
import java.util.logging.Handler;
import java.util.logging.Logger;
import java.util.logging.SimpleFormatter;

class Login {

    private String username = "";                                                        //username of server manager
    private String password = "";                                                        //password of server manager
    private String record = "";
    private boolean flag = false;

    public synchronized String user_login() {


        Logger logger;                                                                //Reference to Logger class is generated
        Handler fileHandler;
        SimpleFormatter plainText;
        Scanner s;
        int thread_name = 0;
        try {//login details fetched from login.txt file
            BufferedReader br = new BufferedReader(new FileReader("D:/JAVA/assignment1/Login.txt"));
            s = new Scanner(System.in);
            System.out.println("Enter your username: ");
            username = s.nextLine();
            System.out.println("Enter your password: ");
            password = s.nextLine();

            Scanner scan;


            while ((record = br.readLine()) != null) {                    //records fetched line by line

                String[] split = record.split(" ");

                if (username.equals(split[0]) && password.equals(split[1])) //username and password compared with data fetched
                {
                    System.out.println(" LOGIN SUCCESSFULL for" + thread_name);
                    flag = true;
                    logger = Logger.getLogger(Logger.class.getName());
                    logger.setUseParentHandlers(false);
                    File f = new File("D:/JAVA/assignment1/" + username + ".txt");
                    if (!f.exists())
                        f.createNewFile();

                    fileHandler = new FileHandler("D:/JAVA/assignment1/" + username + ".txt", true);//File for writting log is opened in append mode
                    plainText = new SimpleFormatter();
                    fileHandler.setFormatter(plainText);
                    logger.addHandler(fileHandler);
                    logger.info("User " + username + "logged in");

                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        if (flag == false) {
            System.out.println("LOGIN UNSUCCESSFULL!!!! ");
            System.out.println("Try again: ");
            user_login();                                                    //if login fails,user reenter his details
        }
        return username;
    }



}
public class Client_Thread extends Thread {
    static String username = "";                                             //username of server manager
                                                         //password of server manager
    String record = "";
    static String locationname;
    static boolean flag = false;
    Logger logger;                                                                //Reference to Logger class is generated

    int thread_name = 0;

    Client_Thread(int x) {
        thread_name = x;
    }


    @Override
    public void run()                                                //client thread statrs execution
    {
        System.out.println(this.thread_name);
            try {
            Login l = new Login();
            synchronized(l)
            {
                username = l.user_login();
            }
            locationname = username.substring(0, 3);
            if (locationname.equals("MTL"))                                //checks which server's manager logged in
            {
                Registry reg;
                reg = LocateRegistry.getRegistry(2964);
                ServerInterface ms = (ServerInterface) reg.lookup("Mtl");  //looks for reference Mtl in registry for montreal server

                Operations m = new Operations();
                m.Operations1(ms,username);                                    //performs the required function
                //logger.info(Logger.class.getName());
            } else if (locationname.equals("LVL")) {
                Registry reg = LocateRegistry.getRegistry(2965);
                ServerInterface ls = (ServerInterface) reg.lookup("Lvl"); //looks for reference Lvl in registry for laval server
                Operations m = new Operations();
                m.Operations1(ls,username);//performs the required function
            } else if (locationname.equals("DDO")) {
                Registry reg = LocateRegistry.getRegistry(2966);
                ServerInterface ds = (ServerInterface) reg.lookup("Ddo");    //looks for reference Ddo in registry for DDO server
                Operations m = new Operations();
                m.Operations1(ds,username);                           //performs the required function
            }
        } catch (IOException | NotBoundException e1) {
            e1.printStackTrace();
        }
    }
}


public class Client {
    static void test_case1()
    {
        for(int i=0;i<2;i++)
        {
            Client_Thread c = new Client_Thread(i);            //run the new client thread
            c.start();
        }
    }

    public static void main(String arg[]) throws RemoteException, NotBoundException {
    test_case1();
    }

}

输出是这样的: - 0 1 输入你的用户名: 输入您的用户名:

但我应该像: - 输入你的用户名: 输入您的密码:

1 个答案:

答案 0 :(得分:1)

每个线程都会创建自己的Login对象。

因此,同步无效,因为每个线程在Login对象的不同实例上进行同步。

为了实现所需的行为,您必须仅实例化一个Login对象并将其传递给您要使用的所有线程。