概念
一个线程中的实例变量针对其他线程有共享与不共享之分,这个在多线程之间交互时是很重要的一个技术点。
数据不共享的情况
例子
我们先来看二段程序
public class MyThread extends Thread {
private int count = 5;
@Override
public void run() {
super.run();
count --;
System.out.println(this.currentThread().getName() + count);
}
}
public class Run {
public static void main(String[] args) {
MyThread k = new MyThread();
Thread a = new Thread(k, "a");
Thread b = new Thread(k, "a");
Thread c = new Thread(k, "a");
Thread d = new Thread(k, "a");
a.start();
b.start();
c.start();
d.start();
}
}
在这个程序中的输出结果是杂乱的,如下图所示
因为我们无法确保线程运行的原子性,怎么说呢,就是指第一段代码中的
count --;
System.out.println(this.currentThread().getName() + count);
count是一个共享的变量,所以第一行语句修改了count以后,再执行第二行语言时,count可能在这个时间间隔中又被其他线程给改了,
所以我们需要在run()前面加入synchronized来确保程序的原子性。当多个线程执行run()方法时,先判断run方法有没有被 上锁,如果上锁,说明有其他的线程正在执行,必须等其他线程调用结束后才可以执行run方法。而这段代码也叫临界区。synchronized这个单词的意思就是同步,一个接着一个来。
public class MyThread extends Thread {
private int count = 5;
@Override
synchronized public void run() {
super.run();
count --;
System.out.println(this.currentThread().getName() + count);
}
}
所谓非线程安全主要是指多个线程对同一个对象的同一个实例变量进行操作时会出现值被更改,值不同步的情况,进而影响程序 的执行流程。
网友评论