A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© 孟庆波 中级黑马   /  2012-4-22 14:06  /  1633 人查看  /  1 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

多线程处理解决了吞吐量和响应速度的问题,但同时带来了资源共享的问题,如死锁和资源的争用。多线程特别适用于需要不同的资源的任务。为单个资源分配多个线程可能导致同步问题,这种情况下,线程可能会被频繁的阻止以等待其他线程。
同步是指多个线程之间存在着先后执行顺序的关联关系

当两个线程t1和t2有相同的优先级,并且同时在系统上运行,如果把时间片分配给t1使用,它在变量variable1写入某个值,但如果时间片用完时它任然没有写入,这时由于时间片已经分配给t2使用,而t2有恰尝试读取该变量的值,此时读出的就不再是正确的值了。这种情况下,如果使用同步仅允许一个线程使用variable1,在该线程完成对variable1的写入工作后再t2读取这个值,可以避免这种错误。

lock语句:
    private Object lockedobj = new object();
  lock (lockedobj)
    {。。。}
lock关键字作用是:确保一个线程位于代码临界区时,另一个线程不再进临界区。
如果其他线程要进入锁定的代码段,则它将一直等待,直到锁定的对象被释放以后才能进入临界区。
lock关键字将代码标记为临界区,它的实现原理是首先锁定某一个私有的对象,然后执行代码段的语句,当代吗的语句执行完毕后,再解除该锁。
锁定的对象名一般声明为Object类型,注意不要声明为值类型。声明类型为 private
临界区的代码不宜过多。

1,先定义类
LockExample
public class LockExample
    {
        private Object lockedobj = new object();
        int balance;
        Form1 form1;
        Random r = new Random();
        public LockExample(int initial, Form1 form1)
        {
            this.form1 = form1;
            this.balance = initial;
        }
        /// <summary>
        /// 取款
        /// </summary>
        /// <param name="amount">取款金额</param>
        /// <returns>取款</returns>
        public int Withdraw(int amount)
        {
            if (balance < 0)
            {
                form1.AddListBoxItem("余额" + balance + "没有了");

            }
            lock (lockedobj)
            {
                if (balance >= amount)
                {
                    string str = Thread.CurrentThread.Name + "取款。。。";
                    str += string.Format("取款前金额:{0,-6} 取款:{1,-6}", balance, amount);
                    balance = balance - amount;
                    str += "取款后金额:" + balance;
                    form1.AddListBoxItem(str);
                    return amount;
                }
                else
                {
                    return 0;
                }
            }

        }

        //自动取款
        public void DoTransaction()
        {
            for (int i = 0; i < 10; i++)
            {
                Withdraw(r.Next(1, 100));
            }
        }

    }


2、新建一个窗体

   public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            listBox1.Items.Clear();
           Thread[] threads = new Thread[10];
           LockExample lockex=new LockExample (1000,this );
            for (int i = 0; i < 10; i++)
            {
                Thread t = new Thread(lockex.DoTransaction);
                t.Name = "线程" + i;
                threads = t;
            }
            for (int i = 0; i < 10; i++)
            {
                threads.Start();
            }
        }

        public delegate void AddListBoxItemDelegate(string str);
        public void AddListBoxItem(string str)
        {
            if (this.listBox1.InvokeRequired)
            {
                AddListBoxItemDelegate d = AddListBoxItem;
                listBox1.Invoke(d, str);
            }
            else
            {
                listBox1.Items.Add(str);
            }
        }
    }
结果为:

评分

参与人数 1技术分 +3 收起 理由
宋天琪 + 3

查看全部评分

1 个回复

倒序浏览
不错 学习
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马