欢迎访问悦橙教程(wld5.com),关注java教程。悦橙教程  java问答|  每日更新
页面导航 : > > 文章正文

Java线程之线程同步,java线程同步,多线程的使用为我们的程序

来源: javaer 分享于  点击 44639 次 点评:261

Java线程之线程同步,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 修饰符 * @author 五斗米 * @blog <a href="http://blog.csdn.net/mq612">http://blog.csdn.net/mq612 */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();    }}//该片段来自于http://byrx.net
相关栏目:

用户点评