黑马程序员技术交流社区
标题:
同步问题
[打印本页]
作者:
苏小惠
时间:
2014-1-7 22:01
标题:
同步问题
本帖最后由 苏小惠 于 2014-2-24 18:56 编辑
同步是为了解决线程安全:那具体什么时候用同步代码块,什么时候用同步函数?
作者:
黑马IT学员
时间:
2014-1-7 22:30
同步函数 同步代码块的另一种方式
/*
需求:
银行有一个金库。
有两个储户分别存300元,每次存100,存3次。
目的:给程序是否有安全问题,如果有,如何解决?
如何找到问题;
1,明确那些代码是多线程运行代码
2,明确共享数据,
3,明确多线程运行代码中些数据是操作共享数据的。
*/
class BankAdd
{
int num;
//Object ob=new Object();
public synchronized void add(int x){//同步函数 同步代码块的另一种方式。
//(ob){
num=num+x;
try{Thread.sleep(10);}catch(Exception e){}
System.out.println("num="+num);
//}
}
}
class Bank implements Runnable
{
BankAdd ba=new BankAdd();
public void run(){
for(int x=0;x<3;x++){
ba.add(100);
//System.out.println(Thread.currentThread().getName());
}
}
}
class BankTest
{
public static void main(String[] args)
{
Bank b=new Bank();
Thread t1=new Thread(b);
Thread t2=new Thread(b);
t1.start();
t2.start();
}
}
作者:
黑马IT学员
时间:
2014-1-7 22:32
在java中,当同步代码块和同步函数一起使用时,为什么同步代码块的Thread.sleep()时间要小于同步函数,例如售票,当同步函数Thread.sleep()时间中的小于同步代码块时,无论多少售票点,都只能是同一窗口售出2张票......
作者:
豆晨阳
时间:
2014-1-7 22:35
1.同步代码块,使用的锁可以是任意对象,但是操作共享资源时,锁必须唯一!
2.同步函数,使用的锁是this!
package com.gc.thread;
public class SynchronizdMethod implements Runnable {
//共享资源
private int num = 1000;
//不同的线程进入不同的同步代码中,验证同步函数使用的锁与同步代码块的锁是否一致
//如果不一致,则会导致数据混乱!
boolean flag = true;
@Override
public void run() {
if(flag) {
//改变标记,当b线程开启后,执行run(),就会进入到同步函数中
flag = false;
while(true) {
//同步代码块。判断 num>0 和 num-- 都是对共享资源进行操作,所以要放在同步代码块中
synchronized(this) {
//只要本次的同步代码块中的代码没有执行完,其它线程无法进入,因为锁没有释放
if(num>0)
System.out.println(Thread.currentThread().getName() + ": code segment--->" + num--);
}
}
} else {
while(true)
anotherThread();
}
}
//同步函数---使用函数对操作共享资源的代码进行封装,再将锁声明在方法上
//使用的锁是this,即传入Thread构造函数中的Runnable子类对象
private synchronized void anotherThread() {
if(num>0)
System.out.println(Thread.currentThread().getName() + ": method--->" + num--);
}
}
package com.gc.thread;
public class Demo {
public static void main(String[] args) {
SynchronizdMethod runnable = new SynchronizdMethod();
//传入同一个Runnable接口子类对象,让多线程操作Runnable中封装的共享资源
Thread a = new Thread(runnable);
Thread b = new Thread(runnable);
//开启线程 【注意:一个线程只能调用1次start(),多次调用将抛"线程运行状态异常"】
a.start();
//让主线程睡眠一小会,让a线程先执行,a线程将执行同步代码块中的代码
try {
Thread.sleep(10);//主线程睡眠的目的:让a线程先进入到同步代码块中,将标记改为false
} catch (InterruptedException e) {
e.printStackTrace();
}
//a线程改变flag标记之后,再开启b线程,让b线程执行同步函数中的代码
b.start();
}
}
作者:
黄晓鑫
时间:
2014-1-21 21:10
当run方法中的代码都是多线程同步代码时 就用同步代码块 并且要保证该同步函数不是静态的
欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/)
黑马程序员IT技术论坛 X3.2