java线程(二)线程同步问题

来源:互联网 发布:mac 变色龙 开机引导 编辑:程序博客网 时间:2024/05/15 23:45

线程的同步?

如果两口子同时对一个银行账户操作,此账户目前的余额是2000,妻子正要取出2000的时候,丈夫也正要从这个账户中取出2000,结果两人同时取出了2000,这就会出现错误,出现数据不一致问题。

所以我们要解决这个问题,就需要对一个资源独占一个时间,在这个人操作这个资源的时候需要加上一把锁,也就是一个人去厕所的时候会独占一个坑一样,不允许别人进入。

 

 

例如当两个线程同时抢占一个资源时候:

//实现Runnable接口。

public class  TestSync implements Runnable

{

Timertimer = newTimer();

public static void main(String[]args)

{

TestSync test = newTestSync();

Thread t1 = newThread(test);

Thread t2 = newThread(test);

//系统内部的函数,为了设置线程的名称。

t1.setName("t1");

t2.setName("t2");

t1.start();

t2.start();

 

}

 

//覆盖Runnable接口中的抽象方法。

public void run()

{

timer.add(Thread.currentThread().getName());

}

 

}

 

class Timer

{

//定义静态变量,表示第几个进程进入。

private staticintnum = 0;

public void add(String name)

{

num++;

try

{

Thread.sleep(1);

}

catch(InterruptedException e){}

 

System.out.println(name + ",你是第 " + num +"使用timer的线程");

}

 

}

 

 

 

上述的程序中的两个线程t1 t2同时一个资源进行操作add(),我们运行出现的结果就会看出错误所在。这就是线程的同步问题。

 

 

 

 

 

线程的死锁

是指对方同时需要对方的那个资源,都互不相让,互相等待,这就会出现了死锁。两个对象的死锁,两辆对面的车,过同一座桥的时候都会互相等待着对方让路,如果互不想让就永远的等待下去。

犹如经典的多个对象的死锁,"哲学家进餐问题",每个人的左手都有一只筷子,能拿到自己右边人的筷子就可以吃饭,大家都是处在同一种情况,形成一个环状的等待。

 

死锁的模拟:

//模拟死锁。解决死锁问题。

publicclass  TestDeadLockimplements Runnable

{

//定义标志位。

publicint flag = 1;

//实例化两个对象。

staticObject o1 = new Object();

staticObject o2 = new Object();

//方法调用。

publicvoid run()

{

System.out.println("flag="+ flag);

if(flag== 1)

{

          //独占资源的时候。

synchronized(o1)

{

try

{

Thread.sleep(500);

}catch(Exceptione)

{

e.printStackTrace();

}

synchronized(o2)

{System.out.println("1");}

}

}

 

if(flag == 0)

{

synchronized(o2)

{

try

{

Thread.sleep(500);

}catch(Exceptione)

{e.printStackTrace();}

synchronized(o1)

{System.out.println("0");}

 

}

}

}

 

publicstatic void main(String[]args)

{

TestDeadLocktd1 = newTestDeadLock();

TestDeadLocktd2 = newTestDeadLock();

td1.flag = 1;

td2.flag = 0;

 

Thread t1 = newThread(td1);

Thread t2 = newThread(td2);

 

t1.start();

t2.start();

}

 

}

 

 

如果b是资源,我们应该把访问b的每个方法都考虑到,因为每个方法都可以改变其值,所以我们应该把每一个访问这个值的方法都进行枷锁。

 

解决更多的死锁问题,可能要增加锁的粒度来解决了,有时候需要把访问这个资源的所有方法都加上锁,也就是排队过桥的人不只是有一个,我们应该给每个人一把锁。