线程同步方式有很多种,其中一种便是synchronized,下面先用一个例子来说一下它的两种应用场景:
package thread;
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(){
timer.add(Thread.currentThread().getName());
}
}
class Timer{
private static int num=0;
//public synchronized void add(String name){第二种方式处理
public void add(String name){
//synchronized (this) {第一种方式处理线程同步
num++;
try{
Thread.sleep(1);
}catch(InterruptedException e){
}
System.out.println(name+",你是第"+num+"个使用timer的线程");
//}
}
}
如果用debug模式下慢点儿调试,输出结果是:
t1,你是第1个使用timer的线程
t2,你是第2个使用timer的线程
如果用start模式下慢点儿调试,输出结果是:
t2,你是第2个使用timer的线程
t1,你是第2个使用timer的线程
package thread;
public class TestDeadLock implements Runnable{//第三步
public int flag=1;//第二步
static Object o1=new Object(),o2=new Object();
public void run(){
System.out.println("flag="+flag);
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();
}
}
在实践的过程中突然想到一个问题:
线程执行快慢与它的启动顺序有关吗?
后来在反复验证后发现,他们并没有直接关系。
上面的情况在很多情况下还是容易引起线程死锁的,像下图这样,一直在等待对方释放:
可以通过加大锁的粒度来减少死锁的情况。
像上图这样,加了同步效率降低,不同步数据不一致
不允许朵儿线程同时改,但允许多个线程同时读
打印结果:2000
为什么??
注意:如果两个方法改了同一个值,两个方法都应该加同步