synchronized二三事3

来源:互联网 发布:java 协议解析 编辑:程序博客网 时间:2024/06/05 06:24

1.Java多线程核心技术里面关于synchronized的讲解多达到50多页,组件synchronized多重要,可以仔细看一下这本书,提高认知。

2、释放与不释放同步锁

(1)线程释放同步锁:

当前线程的同步方法或者同步代码块执行完;

遇到break,return会释放同步锁,但是同步方法块和同步方法会继续执行

发生Error或者Exception会释放同步锁,同时同步的程序终止;

遇到wait,当前线程暂停,并释放锁。

(2)线程不释放同步锁

调用Thread.sleep()Thread.yeild()方法,线程暂停但不释放同步锁。

调用suspend将线程挂起时,虽然线程进入阻塞状态但是不释放同步监视器。

3.例子

(1)多线程调用同一个方法是随机的,从打印结果来看是同步的,即A的执行和退出是成对出现的,但是线程A和线程B的执行时随机的、这是因为两个线程重复调用一个方法,就能体现出随机性了。

class Service{private List list=new ArrayList();synchronized public void add(String userName){System.out.println(Thread.currentThread().getName()+" 执行了add方法");list.add(userName);System.out.println(Thread.currentThread().getName()+" 退出了add方法");}synchronized public int getSize(){System.out.println(Thread.currentThread().getName()+" 执行了get方法");System.out.println(Thread.currentThread().getName()+" 退出了get方法");return list.size();}}public class Run extends Thread{private Service s;public Run(Service s){this.s=s;}public void run(){super.run();for(int i=0;i<1000;i++){s.add(getName()+(i+1));}}public static void main(String[] args){Service s=new Service();Run r1=new Run(s);Run r2=new Run(s);r1.setName("ThreadA");r2.setName("ThreadB");r1.start();r2.start();}}

ThreadA 执行了add方法ThreadA 退出了add方法ThreadB 执行了add方法ThreadB 退出了add方法ThreadB 执行了add方法ThreadB 退出了add方法ThreadA 执行了add方法ThreadA 退出了add方法ThreadB 执行了add方法ThreadB 退出了add方法ThreadA 执行了add方法ThreadA 退出了add方法ThreadB 执行了add方法ThreadB 退出了add方法


(2)因为上面多个线程调用同一个方法时是随机的,所以当两个线程执行过程中有分支出现,则就有可能出现脏读的现象。理论上s中只能添加一个元素,但是因为存在分支,两个线程以异步的形式执行get函数

class Service2{public Service addService(Service s,String data){if(s.getSize()<1){try {Thread.sleep(2000);//模拟远程取数耗时,便于线程B的启动} catch (InterruptedException e) {// TODO Auto-generated catch blocke.printStackTrace();}s.add(data);System.out.println(Thread.currentThread().getName()+"加入了元素"+data);}return s;}}public class Run extends Thread{private Service s;private Service2 s2;public Run(Service s,Service2 s2){this.s=s;this.s2=s2;}public void run(){super.run();s2.addService(s,getName());}public static void main(String[] args){Service s=new Service();Service2 s2=new Service2();Run r1=new Run(s,s2);Run r2=new Run(s,s2);r1.setName("ThreadA");r2.setName("ThreadB");r1.start();r2.start();try {Thread.sleep(6000);} catch (InterruptedException e) {// TODO Auto-generated catch blocke.printStackTrace();}System.out.println("s.size="+s.getSize());}}

ThreadA 执行了get方法ThreadA 退出了get方法ThreadB 执行了get方法ThreadB 退出了get方法ThreadB 执行了add方法ThreadB 退出了add方法ThreadA 执行了add方法ThreadB加入了元素ThreadBThreadA 退出了add方法ThreadA加入了元素ThreadAmain 执行了get方法main 退出了get方法s.size=2



1 0
原创粉丝点击