线程的同步?
如果两口子同时对一个银行账户操作,此账户目前的余额是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的每个方法都考虑到,因为每个方法都可以改变其值,所以我们应该把每一个访问这个值的方法都进行枷锁。
解决更多的死锁问题,可能要增加锁的粒度来解决了,有时候需要把访问这个资源的所有方法都加上锁,也就是排队过桥的人不只是有一个,我们应该给每个人一把锁。