java语言中,引入了对象互斥锁的概念,保证共享数据操作的完整性。每个对象都对于一个可称为“互斥锁”的标记,这个标记保证在任一时刻,只能有一个线程访问该对象。
关键字synchroniazed来与对象的互斥锁联系。当某个对象synchronized修饰时,表明该对象在任意时刻只能由一个线程访问。
synchronized的使用方法可以
syschronize (this) {
num ++;
try {
Thread.sleep(1);
} catch ( InterruptedExcetion e ) {}
system.out.println(num);
}
也可以放在方法的声明中,表示整个方法为同步方法,例如:
synchronized public void add(String name) {...}
发生死锁的原因:
多个线程争夺共同资源,发生互相等待其他线程释放已经占有的资源
根本原因:
资源不足;进程推进顺序不当
代码模拟死锁:
共同争夺资源o1、o2
其中一个线程1对o1加锁后睡眠,线程2获得cpu后给o2加锁然后也是睡眠;唤醒线程1线程1要给o2加锁,发现o2锁了,进入阻塞态,o2进入运行态后想对o1加锁,发现o1也被锁了,然后和线程1等待对方资源被释放。
public class TestDeadSyn implements Runnable{
public int flag = 1;
static Object o1 = new Object();
static Object o2 = new Object();
public static void main(String[] args) {
TestDeadSyn t1 = new TestDeadSyn();
t1.flag = 1;
TestDeadSyn t2 = new TestDeadSyn();
t2.flag = 0;
Thread x1 = new Thread(t1);
Thread x2 = new Thread(t2);
x1.start();
x2.start();
}
@Override
public void run() {
System.out.println(flag);
if (flag == 1) {
synchronized (o1) {
//System.out.println("已经锁定o1");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
synchronized (o2) {
System.out.println("已经锁定o2");
}
}
}
if (flag == 0) {
synchronized (o2) {
//System.out.println("已经锁定o2");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
synchronized (o1) {
System.out.println("已经锁定o1");
}
}
}
}
}
解决线程同步的问题是要考虑每个可能改变需要同步的对象的值的方法是否要加锁,加了同步锁是会改变程序的运行的效率。
这里的public synchronized void m1()这个锁只是保证该方法不被访问,而不能保证其他线程通过其他没加锁的方法(能够访问里面的资源)
参考:http://www.cnblogs.com/GnagWang/archive/2011/02/27/1966606.html
注;加了锁的方法不可以被其他线程访问,但是没有加锁的方法仍然是可以被其他线程访问的。
public class TestSyn1 implements Runnable{
static int b = 0;
public void m1() throws Exception{
b = 1000;
Thread.sleep(4000);
System.out.println("b: " + b );
}
public void m2() {
b = 99;
System.out.println(b);
}
public static void main(String[] args) throws InterruptedException {
TestSyn1 s = new TestSyn1();
Thread t1 = new Thread(s);
//Thread t2 = new Thread(s);
t1.start();
Thread.sleep(1000);
s.m2();
}
@Override
public synchronized void run() {
System.out.println("加锁了");
try {
//b = 88;
m1();
//Thread.sleep(1000);
} catch( Exception e) {
e.printStackTrace();
}
}
}
网友评论