Java多线程学习笔记(一)——Java的非线程安全问题

  最近开始学习Java多线程,边看书边做笔记,写一点自己的理解。首先抛出问题:Java中的非线程安全问题。
  非线程安全问题主要是指:多个线程对同一个对象中的同一个实例变量进行操作时会出现值被更改、值不同步的情况,从而影响程序的执行流程。下面代码为一个非线程安全的简单实例:
  

public class LoginServletTest
{
    public static void main(String args[])
    {
        ALogin a = new ALogin();
        BLogin b = new BLogin();
        b.start();
        a.start();
    }
}

class LoginServlet
{
    private static String usernameRef;
    private static String passwordRef;

    synchronized public static void doPost(String username, String password)
    {
        try
        {
            usernameRef = username;
            if(username.equals("a"))
            {
                Thread.sleep(5000);
            }
            passwordRef = password;
            System.out.println("username=" + usernameRef + " password=" + password);

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

class ALogin extends Thread
{
    @Override
    public void run()
    {
        LoginServlet.doPost("a", "aa");
    }
}

class BLogin extends Thread
{
    @Override
    public void run()
    {
        LoginServlet.doPost("b", "bb");
    }
}

  运行结果如下所示:
  

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

  下面我们来分析一下出现这个结果的原因:
  

  1. 首先,main方法中创建的线程a启动后,执行run方法,在run方法中调用了LoginServlet类的静态方法doPost,由于此时doPost方法的username参数为“a”,所以a线程在修改LoginServlet类的usernameRef静态变量值为a后会休眠5秒;
  2. 主线程main在执行a.start()后继续运行,创建了b线程,b线程运行时run方法同样调用了doPost方法,由于doPost方法的username参数不为“a”,所以b线程在修改LoginServlet类的静态变量usernameRef值为b后会继续运行并修改passwordRef的值为bb,然后b线程将结果打印出并结束执行。
  3. a线程休眠5秒苏醒后,会从Thread.sleep(5000);的下一句继续执行,因此a线程会修改passwordRef的值为aa,但是a线程并没有修改usernameRef的值,此时usernameRef值已经被b线程修改为b,所以最后a线程打印出的结果如上。
      这个例子是Java非线程安全中的一个最简单的例子,Java多线程是一个复杂的问题,需要不断深入学习。
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值