/*
此段代码的功能是:
启动两个线程,访问同一个对象的方法.
如果不加synchronized, 当两个线程同时访问这个方法时,会打印出错误的结果.
如果一个对象或者数据,会被两个线程同时访问,调用.最好加上synchronized 同步该方法.
使方法加锁的方法
在方法声明部分加上synchronized, 如 public synchronized void add(String name){... }
或者在方法体内部.加上synchronized (this) {...}包含需要被同步的语句块
只是锁定这个方法.至于方法里的变量和数据没有锁定.
*/
public class TestSync implements Runnable {
Timer timer = new Timer();
public static void main(String[] args) {
TestSync test = new TestSync();
Thread t1 = new Thread(test);
Thread t2 = new Thread(test);
t1.setName("t1");
t2.setName("t2");
t1.start();
t2.start();
}
public void run(){
// 两个线程t1,t2都使用了一个timer对象的add方法
timer.add(Thread.currentThread().getName());
}
}
class Timer{
private static int num = 0;
public synchronized void add(String name){
// 在方法上加锁 synchronized,是同步的意思.实际就是加锁.
// 使得第一个线程用这个方法的时候, 第二个线程不可以访问这个方法.一定要等第一个线程用完了.第二个线程才能用这个方法.
//synchronized (this) { // 同步也可以加在方法体里面.同步一段代码块.this表示当前访问的线程对象
num ++;
try {Thread.sleep(1);}
catch (InterruptedException e) {}
System.out.println(name+", 你是第"+num+"个使用timer的线程");
//}
}
}
/*
死锁的问题:
两个线程需要同步访问两个对象.
第一个线程先拿到了a对象的锁.如果能再拿到b对象的锁就OK了
第二个线程先拿到了b对象的锁,如果能再拿到a对象的锁就OK了.
但是这两个线程永远都拿不到第2个对象的锁.因为第2个对象都被另一个线程占用着.
解决办法:
1.在不考虑性能的前提下,把锁的粒度加大.比如要占用一个房间,把整个大楼都给锁上.
2.一个线程只锁定一个对象,不要锁定很多对象.如果需要锁定很多对象.这个对象可能就被其他线程事先锁住了.
*/
public class TestDeadLock implements Runnable {
public int flag = 1;
static Object o1 = new Object(), o2 = new Object();
public void run() {
if(flag == 1) {
synchronized(o1) {
try {
Thread.sleep(500);
} catch (Exception e) {
e.printStackTrace();
}
synchronized(o2) {
System.out.println("1");
}
}
}
if(flag == 0) {
synchronized(o2) {
try {
Thread.sleep(500);
} catch (Exception e) {
e.printStackTrace();
}
synchronized(o1) {
System.out.println("0");
}
}
}
}
public static void main(String[] args) {
TestDeadLock td1 = new TestDeadLock();
TestDeadLock td2 = new TestDeadLock();
td1.flag = 1;
td2.flag = 0;
Thread t1 = new Thread(td1);
Thread t2 = new Thread(td2);
t1.start();
t2.start();
}
}

669

被折叠的 条评论
为什么被折叠?



