多线程中的synchronized同步方法详解

1、内部私有变量线程安全

“非线程安全”的问题出现在实例变量中,而在方法的内部的私有变量使不存在“非线程安全问题”的,永远都是线程安全的。这是方法内部的变量使私有的特性造成的。

2、实例变量“非线程安全”

如果多个线程一起访问一个对象中的实例变量,就可能会出现“非线程安全”的问题,如果访问的对象中有多个实例变量,则很可能会出现运行结果交叉的问题。
下面看个例子:
写个仿servlet类

package controller;

public class LoginServlet {
	private static String userName;
	private static String password;
	public static void doPost(String user,String pass){
		try{
			userName = user;
			if (userName.equals("a")){
				Thread.sleep(1000);
			}
			password = pass;
			System.out.println("userName = " + userName + ",password = " + password);
		}catch(InterruptedException e){
			e.printStackTrace();
		}
	}
}

两个线程类:

package ExThread;
import controller.LoginServlet;

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

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

运行类:

package ExThread;

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

运行结果:

userName = b,password = bb
userName = b,password = aa

在这里可以发现出现了非线程安全,第二个打印结果本该是:userName = a,这里是因为线程不同步,两个线程都对同一个实例变量进行了更改,最后就出现了非预期的结果。
在这里的解决方法就是在线程共同调用的方法前加上synchronized关键字:

package controller;

public class LoginServlet {
	private static String userName;
	private static String password;
	synchronized public static void doPost(String user,String pass){
		try{
			userNam

你可能感兴趣的:(java多线程,synchronized)