线程同步详解

来源:互联网 发布:java 图形化界面 编辑:程序博客网 时间:2024/06/03 14:07

线程同步方式有很多种,其中一种便是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
为什么??
这里写图片描述

注意:如果两个方法改了同一个值,两个方法都应该加同步

1 0