精华内容
下载资源
问答
  • java 线程锁对象锁的理解

    千次阅读 2017-04-18 14:31:14
  • 深入探析Java线程锁机制

    千次阅读 2012-12-17 15:23:18
    今天在iteye上提了一个关于++操作和线程安全的问题,一位朋友的回答一言点醒梦中人,至此我对Java线程锁有了更加深刻的认识。在这里也做个总结供大家参考。  先看几段代码吧!  代码一: public class ...
          今天在iteye上提了一个关于++操作和线程安全的问题,一位朋友的回答一言点醒梦中人,至此我对Java线程锁有了更加深刻的认识。在这里也做个总结供大家参考。 
    

          先看几段代码吧!

       代码一:

    public class TestMultiThread2 implements Runnable{
    
    	private static Object o = new Object();
    	
    	private static Integer si = 0;
    	
    	private static AtomicInteger flag = new AtomicInteger();
    	
    	@Override
    	public void run() {
    		for(int k=0;k<2000000;k++){
    			synchronized(si){
    				si++;
    			}
    		}
    		flag.incrementAndGet();
    	}
    	public static void main(String[] args) throws InterruptedException{
    		TestMultiThread2 t1 = new TestMultiThread2();
    		TestMultiThread2 t2 = new TestMultiThread2();
    		ExecutorService exec1 = Executors.newCachedThreadPool();
    		ExecutorService exec2 = Executors.newCachedThreadPool();
    		exec1.execute(t1);
    		exec2.execute(t2);
    		while(true){
    			if(flag.intValue()==2){
    				System.out.println("si>>>>>"+si);	
    				break;
    			}
    			Thread.sleep(50);
    		}
    
    		
    	}	
    	
    }

       为了方便看,重复的就不插入了,从代码二到代码四只插入run()方法中的代码,其他地方都一样

      代码二:

        public void run() {  
            for(int k=0;k<2000000;k++){  
                synchronized(o){  
                    si++;  
                }  
            }  
            flag.incrementAndGet();  
        }  

      代码三:

        public void run() {  
            for(int k=0;k<2000000;k++){  
                synchronized(o){  
                    si++;  
                    o = new Object();  
                }  
            }  
            flag.incrementAndGet();  
        }  

        代码四: 

       public void run() {  
            for(int k=0;k<2000000;k++){  
                synchronized(o){  
                    si++;  
                    Object temp = o;  
                    o = new Object();  
                    o = temp;  
                }  
            }  
            flag.incrementAndGet();  
        }  

      有了这四段代码我想问题大概可以说明白了,这里说一下输出吧。

     

      代码一:<4000000

      代码二:=4000000

      代码三:<4000000

      代码四:<4000000(PS:这个结果非常接近4000000)

     

          这里说明一下我测试中碰到的问题,代码四一直没有跑出我想要的结果,主要是开始我设的循环次数太少,其实这里如果要这个现象更加明显一些可以在中间多new 几个Object 如下面的代码五,这样现象就比较明显了.

      代码五:

        public void run() {  
            for(int k=0;k<2000000;k++){  
                synchronized(o){  
                    si++;  
                    Object temp = o;  
                    for(int m=0;m<10;m++){  
                        o = new Object();  
                    }  
                    o = temp;  
                }  
            }  
            flag.incrementAndGet();  
        }  

     为什么会出现上面的现象:

         代码一:当si做++操作后(可以直接看字节码,这里不贴了),在putstatic之前有几步操作,就是我们常说的非原子操作,而这时候si已经不是原来的对象了,这样锁对另外一个线程来说就失效了,我想代码三和代码四就是最好的佐证,代码四更有说服力。当时因为没有出现预想的情况困惑了挺久。

        其实这里用字节码来解释还不是很严谨,最好的当然直接是汇编代码

        如有什么问题还希望各位读者指正。

     

    展开全文
  • 需要说明的是,JAVA的synchronized()方法类似于操作系统概念中的互斥内存块,在JAVA中的Object类型中,都是带有一个内存的,在有线程获取该内存后,其它线程无法访问该内存,从而实现JAVA中简单的同步、互斥操作...

    1、synchronized关键字
       JAVA的进程同步是通过synchronized()来实现的。需要说明的是,JAVA的synchronized()方法类似于操作系统概念中的互斥内存块,在JAVA中的Object类型中,都是带有一个内存锁的,在有线程获取该内存锁后,其它线程无法访问该内存,从而实现JAVA中简单的同步、互斥操作。
      理解了这个,就能理解为什么synchronized(this)与synchronized(static XXX)的区别了。synchronized就是针对内存区块申请内存锁,this关键字代表类的一个对象,所以其内存锁是针对相同对象的互斥操作,而static成员属于类专有,其内存空间为该类所有成员共有,这就导致synchronized()对static成员加锁,相当于对类加锁,也就是在该类的所有成员间实现互斥,在同一时间只有一个线程可访问该类的实例。如果只是简单的想要实现在JAVA中的线程互斥,明白这些基本就已经够了。但如果需要在线程间相互唤醒的话就需要借助Object.wait(), Object.nofity()了。

    2、wait(),sleep()和notify()方法
      Obj.wait()与Obj.notify()必须要与synchronized(Obj)一起使用。也就是wait与notify是针对已经获取了Obj锁进行操作。
      从语法角度来说就是Obj.wait(),Obj.notify必须在synchronized(Obj){…}语句块内;从功能上来说wait就是说线程在获取对象锁后,主动释放对象锁,同时本线程休眠。直到有其它线程调用对象的notify()唤醒该线程,才能继续获取对象锁,并继续执行。相应的notify()就是对对象锁的唤醒操作。但有一点需要注意的是notify()调用后,并不是马上就释放对象锁的,而是在相应的synchronized(){}语句块执行结束,自动释放锁后,JVM会在wait()对象锁的线程中随机选取一线程,赋予其对象锁,唤醒线程,继续执行。这样就提供了在线程间同步、唤醒的操作。
      Thread.sleep()与Object.wait()二者都可以暂停当前线程,释放CPU控制权,主要的区别在于Object.wait()在释放CPU同时,释放了对象锁的控制。

    3、Java中的wait()为什么总是放在while中,而不是if语句中?
    这是由于其它线程(与你的wait()完全无关的其它线程)会调用notifyAll(),而这个线程并不是你的wait()所共同协作的那个线程。因此,每一次被唤醒,你都要检查一次你wait()等待的条件。因而要用while。

    if(条件不满足){
        this.wait();
    }
    ....其他语句

    当其他线程notify()或者notifyAll()的时候,你继续执行其他的语句
    这个时候,也许你的条件依然不满足,所以需要:

    while(条件不满足){
        this.wait();
    }
    .....其他语句

    4、注意
    (1)可以使用wait和notify函数来实现线程间通信。可以用它们来实现多线程(>3)之间的通信。
    (2)永远在synchronized的函数或对象里使用wait、notify和notifyAll,不然Java虚拟机会生成 IllegalMonitorStateException。
    (3)永远在while循环里而不是if语句下使用wait。这样,循环会在线程睡眠前后都检查wait的条件,并在条件实际上并未改变的情况下处理唤醒通知。
    (4)永远在多线程间共享的对象(在生产者消费者模型里即缓冲区队列)上使用wait。
    (5)倾向用 notifyAll()(唤醒所有等待中的线程),而不是 notify()(唤醒其中一个,而其它线程并不会收到任何通知被唤醒)。

    5、使用实例

    //线程A
    synchronized(obj) {
      while(!condition) {
        obj.wait();
      }
      obj.doSomething();
    }

    当线程A获得了obj锁后,发现条件condition不满足,无法继续下一处理,于是线程A就wait() , 放弃对象锁。
    之后在另一线程B中,如果B更改了某些条件,使得线程A的condition条件满足了,就可以唤醒线程A:

    //线程B
    synchronized(obj) {
      condition = true;
      obj.notify();
    }
    展开全文
  • Java线程锁释放

    千次阅读 2016-06-20 23:19:15
    Java线程锁释放
    Java多线程运行环境中,在哪些情况下会使对象锁释放?


    由于等待一个锁的线程只有在获得这把锁之后,才能恢复运行,所以让持有锁的线程在不再需要锁的时候及时释放锁是很重要的。在以下情况下,持有锁的线程会释放锁

    (1)执行完同步代码块,就会释放锁。(synchronized)
    (2)在执行同步代码块的过程中,遇到异常而导致线程终止,锁也会被释放。(exception)
    (3)在执行同步代码块的过程中,执行了锁所属对象的wait()方法,这个线程会释放锁,进
    入对象的等待池。(wait)

    除了以上情况以外,只要持有锁的线程还没有执行完同步代码块,就不会释放锁。
    在下面情况下,线程是不会释放锁的
    (1)执行同步代码块的过程中,执行了Thread.sleep()方法,当前线程放弃CPU,开始睡眠,在睡眠中不会释放锁。
    (2)在执行同步代码块的过程中,执行了Thread.yield()方法,当前线程放弃CPU,但不会释放锁。
    (3)在执行同步代码块的过程中,其他线程执行了当前线程对象的suspend()方法,当前线程被暂停,但不会释放锁
    展开全文
  • java线程锁

    千次阅读 2012-05-11 14:56:56
    我们已经了解了Java线程编程中常用的关键字synchronized,以及与之相关的对象机制。这一节中,让 我们一起来认识JDK 5中新引入的并发框架中的机制。 我想很多购买了《Java程序员面试宝典》之类图书的朋友...
  • 首先整理多线程同步的知识点,开头肯定是要先探讨探讨多线程同步的问题。那么嘛叫线程安全问题呢? 答: 我们知道Jvm虚拟机的设计中线程的执行是抢占式的,线程的执行时间是由底层系统决定的。所以就会有多个线程...
  • java线程 降级

    千次阅读 2018-04-19 21:44:22
    如果当前线程拥有写,然后将其释放,最后再获取读,这种并不能称之为降级,降级指的是把持住(当前拥有的)写,再获取到读,随后释放(先前有用的)写的过程。下面给出一个降级的示例,当数据变动时,...
  • Java线程知识点总结

    千次阅读 2019-03-14 14:38:26
    文章目录Java线程知识点总结进程与线程线程的状态实现线程的几种方式进程和线程的区别Java进程和线程的关系Thread中的start和run方法的区别Thread和Runnable的关系如何实现处理线程的返回值volatile和...
  • java线程锁种类

    千次阅读 2016-03-01 14:50:24
    作为并发共享数据,保证一致性的工具,在JAVA平台有多种实现(如 synchronized 和 ReentrantLock等等 ) 。这些已经写好提供的为我们开发提供了便利,但是的具体性质以及类型却很少被提及。本系列文章将分析JAVA...
  • Java线程锁如何进行数据同步共享

    千次阅读 2011-10-10 15:37:49
    Java线程锁是为了解决数据同步中的数据安全问题,下面我们就来详细的学习下有关于Java线程锁的相关问题。只有不断的学习才能不断的提高自身的相关技术。 大多数应用程序要求线程互相通信来同步它们的动作。在...
  • 详解Java线程锁之synchronized

    千次阅读 2019-06-13 08:36:27
    synchronized是Java中解决并发问题的一种最常用的方法,也是最简单的一种方法。 synchronized的四种使用方式 修饰代码块:被修饰的代码块称为同步语句块,其作用的范围是大括号{}括起来的代码,作用于调用对象 ...
  • Java线程锁对象的改变

    千次阅读 2016-11-22 15:33:01
    在将任何数据类型作为同步时,需要注意的是,是否有多个线程同时持有对象,如果同时持有相同的对象,则这些线程之间就是同步的;如果分别获得对象,这些线程之间就是异步的。 这个时候线程A和B持有的都是...
  • java并发】线程锁技术的使用

    万次阅读 多人点赞 2016-06-04 07:52:09
    Lock好比传统线程模型中的synchronized技术,但是比sychronized方式更加面向对象,与生活中的类似,本身也应该是个对象。两个线程执行的代码片段如果要实现同步互斥的效果,它们必须用同一个Lock对象。是上...
  • Java线程的6种状态及切换(透彻讲解)

    万次阅读 多人点赞 2016-12-24 16:57:03
    2. 运行(RUNNABLE):Java线程中将就绪(ready)和运行中(running)两种状态笼统的称为“运行”。 线程对象创建后,其他线程(比如main线程)调用了该对象的start()方法。该状态的线程位于可运行线程池中,等待被线程...
  • Java 多线程 并发 Java线程面试题

    千次阅读 2018-05-12 00:02:12
    1) 什么是线程线程是操作系统能够进行运算调度的最小单位,它被...Java在语言层面对多线程提供了卓越的支持,它也是一个很好的卖点。2) 线程和进程有什么区别?线程是进程的子集,一个进程可以有很多线程,每条线...
  • 详解Java线程锁之Lock和ReadWriteLock

    千次阅读 2019-06-14 08:00:00
    ReentrantLock是实现了Lock接口的类,属于独享,独享在同一时刻仅有一个线程可以进行访问。Lock接口很简单,实现了如下: public interface Lock { void lock(); void lockInterruptibly() throws ...
  • 二、线程锁(也叫同步锁、互斥锁) 2.1 使用synchronized关键字对方法进行加锁 2.1.1 语法 2.1.2 案例 2.2 使用synchronize关键字对线程方法中的某一部分加锁(同步块的方式) 2.2.1 语法 2.2.2 案例 2.3 静态...
  • 在项目多线程编程中用了ReentrantLock配合Condition来控制线程的加锁和解锁:private void signalAllConnect() { final ReentrantLock lock = this.connectLock; try { lock.lockInterruptibly(); } catch
  • 线程 并发 同步 原子
  • Java 线程安全与优化

    千次阅读 2019-05-25 14:56:53
    什么是线程安全? 线程安全经常会被各种行业大佬或者面试官大佬挂在嘴边,如何找到一个通俗易懂一点的方式解释线程安全呢,伟大的砖家...众多定义中,《Java Concurrency In Practice》的作者Brian Goetz对线程安全...
  • Java提供了多种多线程锁机制的实现方式,常见的有: synchronized ReentrantLock Semaphore AtomicInteger等 ...4种Java线程锁(线程同步) 1.synchronized 在Java中synchronized关键字被常用于维护...
  • Java线程锁,根据值进行加锁

    千次阅读 2011-04-20 20:52:06
    最近在一个需求中 遇到 say(int a) ,有N个线程对这个函数进行访问,不需要对有所线程进行同步,但是当a值相同的线程要进行同步。 之前所看到synchronized 都是 根据对象进行同步。 现在要做的是根据值进行同步...
  • 同步 /并发/ 读写,显示, ReentrantLock与Condition.> 线程的同步与互斥(同步线程与异步线程线程同步和异步问题) Java 虚拟机中的同步(Synchronization)基于进入和退出管程(Monitor)对象实现, 无论...
  • Java线程-7】阅尽Java千般

    千次阅读 2020-03-31 15:40:46
    前文描述了Java线程编程,多线程的方式提高了系统资源利用和程序效率,但多个线程同时处理共享的数据时,就将面临线程安全的问题。 例如,下面模拟这样一个场景:一个售票处有3个售票员,出售20张票。 public ...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 420,699
精华内容 168,279
关键字:

java线程锁

java 订阅