Java中提供了线程同步机制来解决线程安全问题,使多个线程访问同一个资源时不发生冲突。Java中提供了“锁”,用来防止不同的线程在同一时间访问同一个对象或同一个代码块。
提示
Java中的每段代码和对象都有一个控制权限,拿到了这个权限就可以执行这段代码,“锁”即是这个权限。当一个对象的锁被其他线程持有时,当前线程只能等待(线程阻塞在锁池等待队列中);当取到锁后,线程就开始执行同步代码(被synchronized修饰的代码);线程执行完毕后,锁会立马归还,在锁池中等待的某个线程就可以拿到锁来执行代码,这样就保证了同步代码在同一时刻只有一个线程在执行。
1.同步代码块
Java中使用synchronized关键字来声明同步代码块,也就是所谓的“锁”,它可以有效地防止多个线程同时访问同一个代码块而造成的冲突。synchronized定义代码块格式如下:
共享代码块通常放在synchronized定义的区域内,当线程访问这个代码块时,首先会检测这个代码块是否被其他线程“锁住”了,如果已被“锁住”,则直到其他线程使用完,锁被释放了,这个代码块才可以继续被访问。Object类会标识出这个对象是否被锁,与这个类相关联的线程可以互斥地使用该类对象的锁。下面看一个使用synchronized关键字声明同步代码块的示例。
动手写16.5.2
在上面示例中,线程在进入synchronized代码块之前会先获取key对象的锁,直到key的锁被释放才会执行下一个线程,此时会避免key自增线程安全导致的key值重复的情况发生,其运行结果为:(www.xing528.com)
图16.5.2 synchronized同步代码块
在使用synchronized时,要尽量避免使用sleep()和yield()方法,因为被锁住的程序占用着对象锁,当程序休眠时,其他线程只能等待代码块被执行完后才能开始执行,这样会大大降低程序的运行效率;同时锁一直被占用着,系统内存资源也一直在无意义地消耗。
2.同步方法
同步方法是指在方法前面使用synchronized关键字修饰,定义格式如下:
类中可以有多个同步方法,当调用了对象的其中一个同步方法时或其已被一个线程占用时,该对象的其他同步方法必须等待当前占用的同步方法执行完后才能被执行。Java中每个Class类也对应着一把锁,也可以用synchronized关键字对静态成员方法进行修饰,控制线程对类中成员方法的访问。
动手写16.5.3
动手写16.5.3与动手写16.5.2的运行结果相同,不再赘述。
免责声明:以上内容源自网络,版权归原作者所有,如有侵犯您的原创版权请告知,我们将尽快删除相关内容。