自定义线程中的实例变量可以分为两类:共享变量和不共享变量。
1.不共享:每个线程都有自己的变量,不与其他线程共享。
public class ThreadVariable extends Thread {
private int count =3;
public ThreadVariable(String name){
super();
this.setName(name);
}
public static void main(String[] args) {
ThreadVariable tv1 = new ThreadVariable("A");
ThreadVariable tv2 = new ThreadVariable("B");
ThreadVariable tv3 = new ThreadVariable("C");
tv1.start();
tv2.start();
tv3.start();
}
@Override
public void run() {
// TODO Auto-generated method stub
super.run();
while(count>0){
count--;
System.out.println(Thread.currentThread().getName()+":count="+count);
}
}
}
结果输出:
A:count=2
C:count=2
B:count=2
C:count=1
A:count=1
C:count=0
B:count=1
A:count=0
B:count=0
2.共享:多个线程可以访问同一个变量
(1) 不上锁时候的情况:
public class TestVariable2 extends Thread {
private int count=5;
public static void main(String[] args) {
TestVariable2 t=new TestVariable2();
Thread t1=new Thread(t,"A");
Thread t2=new Thread(t,"B");
Thread t3=new Thread(t,"C");
Thread t4=new Thread(t,"D");
Thread t5=new Thread(t,"E");
Thread t6=new Thread(t,"F");
t1.start();
t2.start();
t3.start();
t4.start();
t5.start();
t6.start();
}
@Override
public void run() {
// TODO Auto-generated method stub
count--;
System.out.println(this.currentThread().getName()+":count="+count);
}
}
结果输出:
B:count=3
A:count=1
D:count=1
C:count=2
E:count=0
F:count=-1
很明显,结果不是依次递减的,不是我们想要的结果。
因为这个现在是非线程安全的。
非线程安全:指的是多个线程对同一个对象的同一个实例变量进行操作时候会出现值被更改、值不同步的情况,进而影响程序的执行结果。
解决办法:在run()方法前加上 synchronized 关键字,这样就是给run()方法进行了上锁。在多个线程执行run()方法的时候,要先判断它有没有被上锁。如果上锁,说明其他线程正在调用run()方法,必须要等待其他线程对run()方法调用完成之后,才可以执行run()方法。这样就实现了排队使用run()方法。
synchronized关键字:可以再任意对象以及方法上上锁,加锁的这段代码成为 “互斥区” 或者 “临界区”。