java线程同步机制以及对象锁机制
来源:互联网 发布:sql 查询过期时间 编辑:程序博客网 时间:2024/06/06 00:15
一、java线程同步机制以及对象锁
1、线程同步
众所周知,在多线程编程中,多个 线程同时对同一个资源进行访问,就可能会出现这样的情况-----这几个线程根据时间片机制会争向访问该资源,特别是在访问某一静态变量
的时候,比如我们所谓的火车票卖票系统,设置一个静态变量 static int ticketCount; 多个线程同时买票,每卖一张票 ticketCount计数器就减1,并且不能使得ticketConut小于
0(即当ticketCount为0的时候就结束卖票)。如果不使用同步机制的情况下,某个线程在执行 卖票的run方法的时候,另一个线程也可能进入,使得 ticketCount计数器小于0。所
以在这种情况下就得使用java的同步机制来做。
同步机制是由synchoronized关键字修饰的,一段synchronized的代码被一个线程执行之前,他要先拿到执行这段代码的权限,在 java里边就是拿到某个同步对象的锁(一个
对象只有一把锁); 如果这个时候同步对象的锁被其他线程拿走了,他(这个线程)就只能等了(线程阻塞在锁池 等待队列中)。 取到锁后,他就开始执行同步代码(被
synchronized修饰的代码);线程执行完同步代码后马上就把锁还给同步对象,其他在锁池中 等待的某个线程就可以拿到锁执行同步代码了。这样就保证了同步代码在统一时刻只
有一个线程在执行。
2、线程同步的方式
(1)synchoronized关键字修饰成员方法
- public class ThreadTest extends Thread {
- private int threadNo;
- public ThreadTest(int threadNo) {
- this.threadNo = threadNo;
- }
- public static void main(String[] args) throws Exception {
- for (int i = 1; i < 10; i++) {
- new ThreadTest(i).start();
- Thread.sleep(1);
- }
- }
- @Override
- public synchronized void run() {
- for (int i = 1; i < 10000; i++) {
- System.out.println("No." + threadNo + ":" + i);
- }
- }
- }
以上这个例子就是首先创建10个线程,然后分别数数从1到9999,通过同步,我们本来想看到的是一个线程从1数到9999,然后第二个开始数,但是控制台的打印的结果还
是杂乱无章的,各个线程争相数数,没有做到我们想要的同步效果。这是为什么呢??
实际上,对于成员方法加上synchronized关键字,是以这个成员方法所在的对象本身作为对象锁,在上例中,就是以ThreadTest类的一个具体对象,也就是该线程自身作
为对象锁的;一共10个线程,每个线程持有自己线程对象的那个对象锁,必然不能产生同步的效果。怎么样才能使得对这些线程进行同步呢??毫无疑问,如果能够使得这些
线程拥有共享且唯一的对象锁,这样的问题就会迎刃而解。
2、同步代码块
- public class ThreadTest2 extends Thread {
- private int threadNo;
- private String lock;
- public ThreadTest2(int threadNo, String lock) {
- this.threadNo = threadNo;
- this.lock = lock; }
- public static void main(String[] args) throws Exception {
- String lock = new String("lock");
- for (int i = 1; i < 10; i++) {
- new ThreadTest2(i, lock).start();
- Thread.sleep(1);
- }
- }
- public void run() {
- synchronized (lock) {
- for (int i = 1; i < 10000; i++) {
- System.out.println("No." + threadNo + ":" + i);
- }
- }
- }
- }
在run方法中加入一个静态代码块,并引入一个通过构造方法赋值的 私有变量 lock,这个new出来的String 变量是存放在堆内存上的,它是唯一的,各个线程共同享有该
lock变量,该lock变量就是所谓的对象锁,这样做就能做到同步的效果。
3、使用synchronized修饰静态方法
- public class ThreadTest3 extends Thread {
- private int threadNo;
- private String lock;
- public ThreadTest3(int threadNo) {
- this.threadNo = threadNo;
- }
- public static void main(String[] args) throws Exception {
- for (int i = 1; i < 20; i++) {
- new ThreadTest3(i).start();
- Thread.sleep(1);
- }
- }
- public static synchronized void abc(int threadNo) {
- for (int i = 1; i < 10000; i++) {
- System.out.println("No." + threadNo + ":" + i);
- }
- }
- public void run() {
- abc(threadNo);
- }
- }
上例中,我们在run方法中,调用一个静态的abc方法,这个静态abc方法被synchronized所修饰,同样做到了同步效果。
下面我们来分析下第三种同步锁机制:我们知道静态方法是属于类的,由于在JVM中,所有被加载的类都有唯一的类对象,具体到本例,就是唯一的
ThreadTest3.class对象。不管我们创建多少个该类的实例,它的对象实例只有一个。对于同步静态方法,对象锁就是该静态方法所在的类的Class实例。
二、总结
使用synchronized修饰成员方法和静态方法,他们的主要区别就是静态方法的对象锁是类实例,且类实例是唯一的,而成员变量的对象锁是该类的实例,每个线程可以分别
拥有不同的实例对象。另,单例模式下成员方法能够起到同步的效果。
- java线程同步机制以及对象锁机制
- java线程同步机制
- JAVA线程同步锁机制分析
- JAVA线程同步锁机制分析
- JAVA线程同步锁机制分析
- JAVA线程同步锁机制分析
- JAVA线程同步锁机制分析 .
- JAVA线程同步锁机制分析
- Java线程新同步机制
- java多线程Thread线程同步与互斥、锁机制
- Java线程同步机制深刻阐述
- Java synchronized同步线程机制(三)
- Java synchronized同步线程机制(二)
- Java synchronized同步线程机制(一)
- 转载:Java高级-线程同步机制实现
- java的内存模型&线程同步机制
- 【总结】Java线程同步机制深刻阐述
- java线程安全与同步机制
- Flash erase/program 检查方法
- 计蒜客 query on a string
- kuangbin KMP E题
- UrJTAG 使用和扩展
- Test5
- java线程同步机制以及对象锁机制
- 使用RecyclerView实现ListView,GridView的效果(上下,左右滑动),拖拽与滑动删除
- 思维导图的三招十八式之梳理
- linux文件描述符限制和单机最大长连接数
- Android 不锁屏
- NoSuchMethodError
- BOOT启动阶段的初始化
- Cygwin编译可执行文件独立运行
- 基于react-native-swiper 封装的bannerView