`
anson_xu
  • 浏览: 502739 次
  • 性别: Icon_minigender_1
  • 来自: 惠州
社区版块
存档分类

关于JAVA多线程同步

    博客分类:
  • java
 
阅读更多
因为需要,最近关注了一下JAVA多线程同步问题。JAVA多线程同步主要依赖于若干方法和关键字。将心得记录如下:


1  wait方法:
        该方法属于Object的方法,wait方法的作用是使得当前调用wait方法所在部分(代码块)的线程停止执行,并释放当前获得的调用wait所在的代码块的锁,并在其他线程调用notify或者notifyAll方法时恢复到竞争锁状态(一旦获得锁就恢复执行)。
        调用wait方法需要注意几点:
        第一点:wait被调用的时候必须在拥有锁(即synchronized修饰的)的代码块中。
        第二点:恢复执行后,从wait的下一条语句开始执行,因而wait方法总是应当在while循环中调用,以免出现恢复执行后继续执行的条件不满足却继续执行的情况。
        第三点:若wait方法参数中带时间,则除了notify和notifyAll被调用能激活处于wait状态(等待状态)的线程进入锁竞争外,在其他线程中interrupt它或者参数时间到了之后,该线程也将被激活到竞争状态。
        第四点:wait方法被调用的线程必须获得之前执行到wait时释放掉的锁重新获得才能够恢复执行。

2  notify方法和notifyAll方法:
        notify方法通知调用了wait方法,但是尚未激活的一个线程进入线程调度队列(即进入锁竞争),注意不是立即执行。并且具体是哪一个线程不能保证。另外一点就是被唤醒的这个线程一定是在等待wait所释放的锁。
        notifyAll方法则唤醒所有调用了wait方法,尚未激活的进程进入竞争队列。

3 synchronized关键字:
        第一点:synchronized用来标识一个普通方法时,表示一个线程要执行该方法,必须取得该方法所在的对象的锁。
        第二点:synchronized用来标识一个静态方法时,表示一个线程要执行该方法,必须获得该方法所在的类的类锁。
        第三点:synchronized修饰一个代码块。类似这样:synchronized(obj) { //code.... }。表示一个线程要执行该代码块,必须获得obj的锁。这样做的目的是减小锁的粒度,保证当不同块所需的锁不冲突时不用对整个对象加锁。利用零长度的byte数组对象做obj非常经济。

4 atomic action(原子操作):
        在JAVA中,以下两点操作是原子操作。但是c和c++中并不如此。
        第一点:对引用变量和除了long和double之外的原始数据类型变量进行读写。
        第二点:对所有声明为volatile的变量(包括long和double)的读写。
        另外:在java.util.concurrent和java.util.concurrent.atomic包中提供了一些不依赖于同步机制的线程安全的类和方法。


5 一个例子,该例子模仿多人存取同一个账户:
Account类:
package com.synchronize;

import java.util.HashMap;
import java.util.Iterator;

public class Account {
    private static HashMap<String, Integer> m = new HashMap<String, Integer>();
    private static long times = 0;
    static {
        m.put("ren", 1000);
    }

    public synchronized void save(String name, int num) {
        long tempTime = times++;
        System.out.println("第 " + tempTime + " 次存储" + num + "之前" + name    + "的余额为:" + m.get(name));
        m.put(name, m.get(name) + num);
        this.notify();
        System.out.println("第 " + tempTime + " 次存储" + num + "之后" + name + "的余额为:" + m.get(name));
    }

    public static int get(String name) {
        return m.get(name);
    }

    /**
     * 注意wait的用法,必须在loop中,必须在拥有锁的代码块中。 前者是当被notify的时候要重新进行条件判断,后者是为了释放锁。
     *
     * @param name
     * @param num
     */
    public synchronized void load(String name, int num) {
        long tempTime = times++;
        System.out.println("第 " + tempTime + " 次提取" + num + "之前" + name + "的余额为:" + m.get(name));

        try {
            while (m.get(name) < num) {
                System.out.println("第 " + tempTime + " 次提取" + "余额" + m.get(name) + "不足,开始等待wait。");
                this.wait();
                System.out.println("第 " + tempTime + " 次提取操作被唤醒");
            }
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        m.put(name, m.get(name) - num);
        System.out.println("第 " + tempTime + " 次提取" + num + "之后" + name + "的余额为:" + m.get(name));
    }
}


User类:
package com.synchronize;

/**
* 这里注意runnable接口的线程是怎么实例化的。new Thread(new User())
* 这里成功展示了多个用户存取同一个账户的多线程实例,通过多线程同步,保证了安全的执行。
* @author abc
*
*/
public class User implements Runnable {
    private static Account account = new Account();
    private final int id;
  
    User(int i){
        id=i;
    }
  
    public void run() {
        int tempMoney = 100;
        account.load("ren", tempMoney);
        try {
            Thread.sleep(3000);
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        account.save("ren", 100);
        System.out.println("线程"+id+"完毕========================================================");
    }

    public static void main(String[] args) {
        for (int i = 0; i < 100; i++) {
            new Thread(new User(i)).start();
        }
    }
}

后续:请额外关注 ThreadLocal、JDK 5 中增加的 Lock 接口。
分享到:
评论

相关推荐

    Java多线程同步论文.doc

    Java多线程同步论文.doc

    java多线程同步例子

    java多线程同步互斥访问实例,对于初学者或是温故而知新的同道中人都是一个很好的学习资料

    java多线程同步分析

    java多线程同步分析java多线程同步分java多线程同步分析析java多线程同步分析java多线程同步分析

    java 多线程同步方法的实例

    java 多线程同步方法的实例 java 多线程同步方法的实例 java 多线程同步方法的实例

    Java多线程同步.pdf

    Java多线程同步.pdf

    java多线程同步问题

    多线程注意:wait()方法的调用要有判定条件常用 while () obj.wait(timeout, nanos); ... // Perform action appropriate to condition } synchronized会影响共享数据,但对其他语句的执行不会有规律了!

    Java多线程同步具体实例讲解 .doc

    Java多线程同步具体实例讲解 .doc

    Java多线程同步具体实例.doc

    Java多线程同步具体实例.doc

    java多线程经典案例

    java多线程经典案例,线程同步、线程通信、线程阻塞等经典案例

    Java多线程和同步

    Java线程(二):线程同步synchronized和volatile 详细讲解Java 同步的原理技术资料

    java 多线程同步

    java.util.concurrent 包含许多线程安全、测试良好、高性能的并发构建块。不客气地说,创建 java.util.concurrent 的目的就是要实现 Collection 框架对数据结构所执行的并发操作。通过提供一组可靠的、高性能并发...

    Java多线程编程总结

    Java线程:线程的同步-同步方法 Java线程:线程的同步-同步块 Java线程:并发协作-生产者消费者模型 Java线程:并发协作-死锁 Java线程:volatile关键字 Java线程:新特征-线程池 Java线程:新特征-有返回值的...

    java多线程编程总结

    详细的讲述了多线程的各种用法 Java线程:概念与原理 Java线程:创建与启动 Java线程:线程栈模型与线程的变量 Java线程:线程状态的转换 Java线程:线程的同步与锁 Java线程:线程的交互 Java线程:线程的调度-休眠...

    基于Java多线程同步技术的简易模拟售票系统实现.pdf

    基于Java多线程同步技术的简易模拟售票系统实现.pdf

    Java多线程机制(讲述java里面与多线程有关的函数)

    Java多线程机制 9.1 Java中的线程 9.2 Thread的子类创建线程 9.3 使用Runable接口 9.4 线程的常用方法 9.5 GUI线程 9.6 线程同步 9.7 在同步方法中使用wait()、notify 和notifyAll()方法 9.8 挂起、恢复和终止线程 ...

    java 多线程 同步详解

    java 多线程同步详解 synchronized 的使用,锁定对象 ,锁定类 区别

    java多线程通信图解

    java 多线程 其实就是每个线程都拥有自己的内存空间,多线程之间的通信,比例A线程修改了主内存(main方法的线程)变量,需要把A线程修改的结果同步到主线程中,这时B线程再从主线程获取该变量的值,这样就实现了...

    java多线程笔记

    三、Java中关于线程的名词解释 3 四、线程的状态转换和生命周期 4 Java线程:创建与启动 7 Java线程:线程名称的设定及获取 10 Java线程:线程栈模型与线程的变量 12 Java线程:线程的调度-休眠 13 Java线程:线程的...

    Java多线程同步机制在售票系统的实现

    编写多线程程序是一件烦琐的技术而且还涉及很多不安全的因素。Java 的出现,使得编写安全高效的多线程技术变得简单,但 ...本文介绍了长途汽车售票系统中所涉及的问题来说明Java 多线程技术同步机制的实现。

    java多线程代码案例(创建线程,主线程,线程优先级,线程组,线程同步,线程间的通信)

    java多线程知识点,源代码案例,代码案例中包括如何创建线程,主线程,线程优先级,线程组,线程同步,死锁,线程间的通信知识点

Global site tag (gtag.js) - Google Analytics