多线程中一定会遇到线程安全的问题,也就是在同一时间N条线程操作了同一变量,这个变量也叫做共享变量。
举例:(错误的示范)
设计一个投票系统,多个人可以对同一个的票数进行投票,下面看具体代码:
代码:
/** * 投票Demo 错误示范 */ public class Test01 extends Thread { //小明的起始票数为0 int count = 0; @Override public void run() { super.run(); count++; System.out.println(this.currentThread().getName() + "投完票之后,小明的票数增加到了:" + count); } public static void main(String[] args) { Test01 test01 = new Test01(); Thread a = new Thread(test01, "小红"); Thread b = new Thread(test01, "小亮"); Thread c = new Thread(test01, "小白"); Thread d = new Thread(test01, "小黑"); a.start(); b.start(); c.start(); d.start(); } }
看代码貌似没什么问题,但是见到打印的语句就会发现问题了:
小红投完票之后,小明的票数增加到了:2 小亮投完票之后,小明的票数增加到了:2 小白投完票之后,小明的票数增加到了:3 小黑投完票之后,小明的票数增加到了:4
明明小红投完票之后,小明的票应该是1,但是却变为了2,这就出现了多线程数据安全的问题,很容易发生共享数据错乱,要想解决这个办法,就应该使用synchronized来解决了。
注意看下面代码的变化:
/** * 投票Demo 错误示范 */ public class Test01 extends Thread { //小明的起始票数为0 int count = 0; //使用synchronized修饰之后就不会出现共享数据安全问题了 @Override synchronized public void run() { super.run(); count++; System.out.println(this.currentThread().getName() + "投完票之后,小明的票数增加到了:" + count); } public static void main(String[] args) { Test01 test01 = new Test01(); Thread a = new Thread(test01, "小红"); Thread b = new Thread(test01, "小亮"); Thread c = new Thread(test01, "小白"); Thread d = new Thread(test01, "小黑"); a.start(); b.start(); c.start(); d.start(); } }
synchronized可以在任意方法和对象上面上锁,加锁这段代码称为“临界点”或者“互斥区”
到这里就可以解决多线程数据安全的问题了,这种问题在工作中是很常见的,一定要注意。