本文实例讲述了Java线程同步的用法。分享给大家供大家参考。具体分析如下:
多线程的使用为我们的程序提供了众多的方便,同时它也给我们带来了以往没有考虑过的麻烦。当我们使用多线程处理共享资源时意外将会发生:比如我们一起外出就餐,每个人都是一个线程,餐桌上的食物则是共享资源,当我看到红烧鸡腿上桌后立即拿起筷子直奔目标,眼看着就得手的时候,突然~~~鸡腿消失了,一个距离盘子更近的线程正在得意地啃着。
为了避免上述问题的发生,Java为我们提供了“synchronized(同步化)修饰符”来避免资源冲突,你可以将资源类中某个函数或变量声明为synchronized(同步化),每个继承自Object的类都含有一个机锁(Lock),它是余生俱来的,不需要编写任何代码来启用它。当我们调用任何synchronized(同步化)函数时,该对象将被锁定,对象中所有 synchronized(同步化)函数便无法被调用,直到第一个函数执行完毕并解除机锁。
import java.awt.BorderLayout; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import javax.swing.JButton; import javax.swing.JFrame; import javax.swing.JPanel; import javax.swing.JScrollPane; import javax.swing.JTextArea; import javax.swing.JTextField; /** * 线程同步 * 我们模拟一个银行存储过程来证明线程同步的必要性以及在Java中进行线程同步的方法 * 重点:synchronized 修饰符 */ public class TestMain5 extends JFrame { private MyAccounts myAccounts = null; // 我的帐号 private JTextField text = null; // 银行存款数额显示 private JTextArea textArea = null; // 交易过程显示 private JButton button = null; // 开始模拟交易的按钮 /** * 构造一个银行存取款界面 */ public TestMain5(){ super("线程同步测试"); myAccounts = new MyAccounts(); text = new JTextField(Integer.toString(myAccounts.inquire()), 10); // 我们在银行中的初始存款为100 textArea = new JTextArea(); textArea.setText("交易日志:"); JScrollPane sp = new JScrollPane(textArea); button = new JButton("开始交易"); button.addActionListener(new ActionListener(){ public void actionPerformed(ActionEvent e) { new Bank("钟楼支行", myAccounts, Bank.DEAL_SAVING, 800); new Bank("高新支行", myAccounts, Bank.DEAL_SAVING, 1300); new Bank("小寨支行", myAccounts, Bank.DEAL_FETCH, 200); new Bank("雁塔支行", myAccounts, Bank.DEAL_FETCH, 400); new Bank("兴庆支行", myAccounts, Bank.DEAL_SAVING, 100); new Bank("土门支行", myAccounts, Bank.DEAL_FETCH, 700); } }); JPanel pane = new JPanel(); pane.add(text); pane.add(button); this.getContentPane().add(pane, BorderLayout.NORTH); this.getContentPane().add(sp); this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); this.setSize(300, 200); this.setLocationRelativeTo(null); this.setVisible(true); } /** * 银行交易大厅类 * 一般银行都会有N个交易大厅,这些大厅可以同时处理多笔业务,这正好符合多线程的特点 */ class Bank extends Thread{ /** * 静态字段:用于表示储存 */ public static final int DEAL_SAVING = 0; /** * 静态字段:用于表示提取 */ public static final int DEAL_FETCH = 1; private int buy = Bank.DEAL_FETCH; // 默认使取款 private int count = 0; private MyAccounts myAccounts = null; // 我的帐号 /** * 构造这个银行交易大厅 * @param name 这个交易大厅的名称 * @param myAccounts 我的银行帐号 * @param buy 行为,参考字段:DEAL_SAVING或DEAL_FETCH * @param count 钱的数量 */ public Bank(String name, MyAccounts myAccounts, int buy, int count){ super(name); this.myAccounts = myAccounts; this.buy = buy; this.count = count; this.start(); } public void run(){ int $count = 0; if(buy == Bank.DEAL_SAVING){ // 如果是存款业务 $count = myAccounts.saving(count); }else if(buy == Bank.DEAL_FETCH){ // 如果是取款业务 $count = myAccounts.fetch(count); } text.setText(Integer.toString($count)); textArea.append("\n" + this.getName() + " " + (buy == Bank.DEAL_SAVING ? "存款": "取款") + " 金额:" + count + " 结余:" + $count); } } /** * 我的帐号 * 进行同步测试 */ class MyAccounts{ private Integer count = 1100; public MyAccounts(){ } /** * 查询我的帐号 */ public int inquire(){ synchronized (count){ return count; } } /** * 存款业务 * @param c 存款的数量 * @return 业务办理完成后的数量 */ public int saving(int c){ synchronized (count){ //return count += c; // 为了能更好的观察,我们将这个简洁的语句注释掉 int $count = inquire(); // 先查询帐户中的存款 $count += c; try { Thread.sleep(1000); // 为了更好的观察,使业务在此停顿1秒钟 } catch (InterruptedException ex) { ex.printStackTrace(); } count = $count; // 最后将总数储存起来 return inquire(); // 返回最新的存款数 } } /** * 取款业务 * @param c 取款的数量 * @return 业务办理完成后的数量 */ public int fetch(int c){ synchronized (count){ //return count -= c; // 为了能更好的观察,我们将这个简洁的语句注释掉 int $count = inquire(); // 先查询帐户中的存款 $count -= c; try { Thread.sleep(1000); // 为了更好的观察,使业务在此停顿1秒钟 } catch (InterruptedException ex) { ex.printStackTrace(); } count = $count; // 最后将总数储存起来 return inquire(); // 返回最新的存款数 } } } public static void main(String [] args){ new TestMain5(); } }
希望本文所述对大家的java程序设计有所帮助。
本文向大家介绍JAVA线程同步实例教程,包括了JAVA线程同步实例教程的使用技巧和注意事项,需要的朋友参考一下 线程是Java程序设计里非常重要的概念,本文就以实例形式对此加以详细解读。具体分析如下: 首先,线程加锁有什么用处呢?举个例子:比如你现在有30000块大洋在银行存着,现在你到银行取钱,当你输入密码完成后,已经输入取款金额,比如你输入的是20000,就是在银行给你拿钱这个时刻,你老婆也去
本文向大家介绍java多线程-同步块实例讲解,包括了java多线程-同步块实例讲解的使用技巧和注意事项,需要的朋友参考一下 java多线程-同步块 Java 同步块(synchronized block)用来标记方法或者代码块是同步的。Java 同步块用来避免竞争。本文介绍以下内容: Java 同步关键字(synchronzied) 实例方法同步 静态方法同步 实例方法中同步块 静态方法中同步块
本文向大家介绍Java线程让步yield用法实例分析,包括了Java线程让步yield用法实例分析的使用技巧和注意事项,需要的朋友参考一下 本文实例讲述了Java线程让步yield用法。分享给大家供大家参考,具体如下: 一 点睛 yield()方法是一个和sleep()方法有点类似的方法,它是Thread类提供的一个静态方法,它也可以让当前正在执行的线程暂停,但它不会阻塞该线程,它只是让线程转入就
本文向大家介绍C#实现多线程的同步方法实例分析,包括了C#实现多线程的同步方法实例分析的使用技巧和注意事项,需要的朋友参考一下 本文主要描述在C#中线程同步的方法。线程的基本概念网上资料也很多就不再赘述了。直接接入 主题,在多线程开发的应用中,线程同步是不可避免的。在.Net框架中,实现线程同步主要通过以下的几种方式来实现,在MSDN的线程指南中已经讲了几种,这里结合作者实际中用到的方式一起说明一
问题内容: 我正在使用Android App,无法将View与硬件同步。让我解释。 1)我从线程1的run方法中基于数组A中存储的随机值(即随机睡眠)对Android的麦克风进行静音和取消静音。 2)我画出反映麦克风静音的蓝色脉冲。这是通过独立的View类完成的。 3)通过从倒数计时器的onTick内调用,我在上面视图中绘制的图形上移动了一条红线。 我以这种方式一个接一个地启动两个线程: 线程1.
主要内容:1 什么是Java 线程同步,2 为什么使用Java线程同步,3 Java同步类型,4 Java线程同步的类型,5 线程互斥,6 Java锁的概念,7 线程并发问题引发数据不一致,8 Java synchronized方法的例子1,9 Java synchronized方法的例子21 什么是Java 线程同步 Java中的同步是控制多个线程对任何共享资源的访问的能力。 Java同步是更好的选择,我们希望只允许一个线程访问共享资源。 2 为什么使用Java线程同步 Java线程同步主要用