线程休眠的问题?

初学多线程,关于sleep有个地方不明白。

代码

package controller;

public class ALogin extends Thread {
    // 假设一个A用户登录
    @Override
    public void run() {
        LoginServlet.doPost("a", "aa");
    }

}
package controller;

public class BLogin extends Thread {
    // 一个B用户登录
    @Override
    public void run() {
        LoginServlet.doPost("b", "bb");
    }
}
package controller;

/**
 * 实现一个解决非线程安全问题
 * 
 * @author Joy
 * 
 */
// 模拟一个servlet
public class LoginServlet {
    static String usernameRef;
    static String passwordRef;

     public static void doPost(String username, String password) {
        try {
            usernameRef = username;
            if (username.equals("a")) {
                // 线程休眠(暂停)5秒
                Thread.sleep(5000);
            }
            passwordRef = password;
            System.out.println("username=" + usernameRef + " password="
                    + passwordRef);

        } catch (Exception e) {
            e.printStackTrace();
        }
    }

}
package TestMain;

import controller.ALogin;
import controller.BLogin;

public class TestMain {
    public static void main(String[] args) {
        // 产生非线程安全,值被改变
        // A线程一开始会进入休眠状态5秒,然后是B线程启动执行。        
        ALogin a = new ALogin();
        a.start();
        
        BLogin b = new BLogin();
        b.start();
    }
}

运行结果

    username=b password=bb
    username=b password=aa

网上的解释线程
图片描述

刚开始a线程暂停五秒,然后b线程执行,打印第一行。
5秒结束后,a线程难道不会启动吗?第二行为什么出现不同值情况?刚看多线程,不太理解,参考书籍《Java多线程编程核心技术》但书中没有解释这个结果,望解答

阅读 3.1k
3 个回答

usernameRef和passwordRef 是多个线程共享变量,多线程访问,需要同步处理。

由于static的存在,按照时序来看,你就明白了。
第二行的输出是你线程A的结果。

再给你补充一下这个知识点吧。

1、static 变量

static 修饰的变量我们称之为静态变量,没有用 static 修饰的变量称之为实例变量,他们两者的区别是:

静态变量是随着类加载时被完成初始化的,它在内存中仅有一个,且 JVM 也只会为它分配一次内存,同时类所有的实例都共享静态变量,可以直接通过类名来访问它。
但是实例变量则不同,它是伴随着实例的,每创建一个实例就会产生一个实例变量,它与该实例同生共死。

所以我们一般在这两种情况下使用静态变量:对象之间共享数据访问方便

2、static 方法

static 修饰的方法我们称之为静态方法,我们通过类名对其进行直接调用。由于他在类加载的时候就存在了,它不依赖于任何实例,所以 static 方法必须实现,也就是说他不能是抽象方法 abstract。
Static 方法是类中的一种特殊方法,我们只有在真正需要他们的时候才会将方法声明为 static。如 Math 类的所有方法都是静态 static 的。

多个线程操作共享资源这就是线程安全的问题。

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题