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

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

本帖最后由 王虎 于 2012-10-8 21:44 编辑

最近学习多线程的知识,遇到两个疑惑:1.多线程安全问题出现原因 ?
                                                               2.同步方法中锁的机制是怎么运作的?请举例说明,最好结合代码或图说明一下

评分

参与人数 1技术分 +1 收起 理由
刘芮铭 + 1 欢迎来15期~~~~

查看全部评分

7 个回复

倒序浏览
因为CPU的随机快速切换线程,当一个线程正在执行到一定部分时,CPU切换到了另一个线程,当两个线程共享一个数据时,第二个线程结束后,已经改变了这个变量,而后又去执行线程1,这是就出现了安全问题。

评分

参与人数 1技术分 +1 收起 理由
唐志兵 + 1 赞一个!

查看全部评分

回复 使用道具 举报
严重BS你啊王虎同志,上课不听讲

点评

同意你的观点,王虎同志真是上课不听课  发表于 2012-10-8 22:10
回复 使用道具 举报
多线程中的安全问题出现的原因是因为有多个线程在操作同一个数据,并且时多条语句的操作,这时就有可能出现在执行到一条语句还没完全执行完的时候会被cpu切换到下一个线程来执行这个语句,就会出现安全问题。

同步中锁的机制就是把有可能出现安全问题的共享数据进行上锁操作,简单的说就是当有一个线程操作这个共享数据时,其他的线程就不可以操作这个数据,只能等到这个线程执行完之后,其他线程才可以进行操作。就像是一个房间里有很多美女,而门外有很多人,每个人都要等着和房间中的每一个美女就行交流,而你进门之后就把门用锁锁着了,这样其他人就进不来了,你就可以慢慢和每一个美女交流了,不用担心其他人把强你风头了,哈哈

评分

参与人数 1技术分 +1 收起 理由
唐志兵 + 1 赞一个!

查看全部评分

回复 使用道具 举报
黑马连家华 发表于 2012-10-8 21:53
严重BS你啊王虎同志,上课不听讲

华哥,不是不听课,是对那个知识点有点模糊,理解不够透彻,所以希望交流一下加深理解啦~
回复 使用道具 举报
你看板儿猪也是这么想的 铁证如山容不得你狡辩!
老师说 一屋子的大便,徐传任弄一屋子美女?把人关厕所里了.
回复 使用道具 举报
王虎 中级黑马 2012-10-8 23:47:32
7#
黑马连家华 发表于 2012-10-8 22:27
你看板儿猪也是这么想的 铁证如山容不得你狡辩!
老师说 一屋子的大便,徐传任弄一屋子美女?把人关厕所里了. ...

人生自古谁无屎,大便才是硬道理儿!
回复 使用道具 举报
本帖最后由 安显杰 于 2012-10-25 19:43 编辑

一个Java程序的多线程之间可以共享数据。当线程以独立的异步方式访问共享数据时,有时候是不安全的或者不符合逻辑的。
比如,两个线程同时存取一个数据流,其中一个对数据进行了修改,而另一个线程仍旧是修改前的数据,这就带来了数据不一致的问题。
1用Java语言的关键字synchronized实现对共享数据同步线程同步是多线程编程的一个重要的技术。
例如模拟一个火车票售票系统,有100张票分别由4个线程完成。importjava.io.
*;classticket//主类{publicstaticvoidmain(Stringargs[])
{SellThreadst=newSellThread();newThread(st).start();
newThread(st).start();newThread(st).start();newThread(st).start();}}
classSellThreadimplementsRunnable{inttickets=100;//总票数publicvoidrun()
{while(true){if(tickets>0){try{Thread.sleep(10);//当前正在执行线程睡眠一会}catch(Exceptione){e.printStackTrace();}System.out.println(Thread.currentThread()
.getName()+"Sell-tickets:"+tickets);tickets--;}}}}
当还剩一张票时,tickets为1时,第一个线程进入if语句中,买了最后一张票,tickets为0,
这是时间片到期了;第二个线程开始运行,买了第0张票,tickets为-1,时间片到期了;
第3个线程进入if语句中,买了第-1张票,tickets为-2,时间片到期;第4个线程进入if语句中,买了第-2张票
,tickets为-3,时间片到期,这种结果是不正确的,像这类错误很难找出原因,在编程时应尽量避免,
这个问题发生主要是因为多个线程同时访问了tick-ets变量。可以采用多线程同步控制机制实现。
在同步机制中,不允许多线程并发执行,同步机制中不允许其他线程并发执行的程序代码段称为临界区,
此程序中if语句体称为临界区,将这段代码用同步来实现。同步有同步块和同步方法
,都是通过synchronized关键字来完成。对同步块而言,在synchronized后加上一个对象,

可以是this对象,这样实现了同步。这时程序执行结果是正确的。将上面程序加上同步块修改importjava.io.*;
classFirstThreadextendsThread//通过Thread类的子类创建的线程{//定义线程的run()
方法publicvoidrun(){System.out.println("FirstThreadisrunning…");}}
classSecondThreadimplementsRunnable//通过Runnable接口创建另一个线程{publicvoidrun()
{System.out.println("SecondThreadisrun-ning…");}}
classMulti_Thread{publicstaticvoidmain(Stringargs[])
//声明主方法{FirstThreadt1=newFirstThread();
//用Thread类的子类创建线程Threadt2=newThread(newSecondThread());
//用Runnable接口类的对象创建线程t1.start();t2.start();//启动线程}
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马