若有多个线程同时操作一个数据,可能会造成数据错乱的情况。
比如说,二个线程同时操作一个int a的对象做加减,其中一个线程t1获取到时间片后,此时a=100,尚未执行,就失去了cpu,另外一个线程t2又获取到了cpu。对a进行运算后,a = 101,这个时候,t1又获取到了cpu,开始对a进行运算,此时a应该为101的,但是,t1中的a其实还是100,这样就造成问题了。
所以要用到线程同步。
1:同步代码块synchronized (this){操作共享数据的代码块}
其中this叫做监视器,又称同步锁,可以由任何类的对象来充当,但是要保证所有的线程对象用的是同一个锁,以识别当前是否有线程在操作同步数据。
实现Runnable的方式,可以用this,若是继承Thread的方式实现的线程,要new一个公用的类对象来充当同步锁,不能用this。因为实现的方式只new了一个实现Runnable的对象,而继承方式,你有几个线程,就要new 几个对象,每个线程的this是不同的。
代码示例:
public class TestSyn {
public static void main(String[] args){window w = new window();
Thread t1 = new Thread(w);
Thread t2 = new Thread(w);
Thread t3 = new Thread(w);
Thread t4 = new Thread(w);
t1.setName("window1");
t2.setName("window2");
t3.setName("window3");
t4.setName("window4");
t1.start();
t2.start();
t3.start();
t4.start();
}
}
class window implements Runnable{
int ticket = 100;
public void run(){
synchronized (this) {
while(true){
if(ticket > 0){
ticket--;
try {
Thread.sleep(10);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName()+":"+ticket);
}else{
break;
}
}
}
}
}
若把实现类中的同步锁拿掉,最后会有为0的结果打印出来。