Java synchronized

Synchronized

Java语言的关键字,当它用来修饰一个方法或者一个代码块的时候,能够保证在同一时刻最多只有一个线程执行该段代码。

当两个并发线程访问同一个对象object中的这个synchronized(this)同步代码块时,一个时间内只能有一个线程得到执行。另一个线程必须等待当前线程执行完这个代码块以后才能执行该代码块。

然而,当一个线程访问object的一个synchronized(this)同步代码块时,另一个线程仍然可以访问该object中的非synchronized(this)同步代码块。

尤其关键的是,当一个线程访问object的一个synchronized(this)同步代码块时,其他线程对object中所有其它synchronized(this)同步代码块的访问将被阻塞。

第三个例子同样适用其它同步代码块。也就是说,当一个线程访问object的一个synchronized(this)同步代码块时,它就获得了这个object的对象锁。结果,其它线程对该object对象所有同步代码部分的访问都被暂时阻塞。

以上规则对其它对象锁同样适用.

wait和notify

import java.util.ArrayList;  
import java.util.List;  

public class Plate {  

    List<Object> eggs = new ArrayList<Object>();  

    public synchronized Object getEgg() {  
        while(eggs.size() == 0) {  
            try {  
                wait();  
            } catch (InterruptedException e) {  
            }  
        }  

        Object egg = eggs.get(0);  
        eggs.clear();// 清空盘子  
        notify();// 唤醒阻塞队列的某线程到就绪队列  
        System.out.println("拿到鸡蛋");  
        return egg;  
    }  

    public synchronized void putEgg(Object egg) {  
        while(eggs.size() > 0) {  
            try {  
                wait();  
            } catch (InterruptedException e) {  
            }  
        }  
        eggs.add(egg);// 往盘子里放鸡蛋  
        notify();// 唤醒阻塞队列的某线程到就绪队列  
        System.out.println("放入鸡蛋");  
    }  

    static class AddThread extends Thread{  
        private Plate plate;  
        private Object egg=new Object();  
        public AddThread(Plate plate){  
            this.plate=plate;  
        }  

        public void run(){  
            for(int i=0;i<5;i++){  
                plate.putEgg(egg);  
            }  
        }  
    }  

    static class GetThread extends Thread{  
        private Plate plate;  
        public GetThread(Plate plate){  
            this.plate=plate;  
        }  

        public void run(){  
            for(int i=0;i<5;i++){  
                plate.getEgg();  
            }  
        }  
    }  

    public static void main(String args[]){  
        try {  
            Plate plate=new Plate();  
            Thread add=new Thread(new AddThread(plate));  
            Thread get=new Thread(new GetThread(plate));  
            add.start();  
            get.start();  
            add.join();  
            get.join();  
        } catch (InterruptedException e) {  
            e.printStackTrace();  
        }  
        System.out.println("测试结束");  
    }  
}  

wait和notify是Object类的方法,在Synchronize代码块中运行。
首先,需要明确,一把锁维护两个线程队列:
阻塞队列和就绪队列。
加了锁的对象在执行wait之后进入阻塞队列,同时本线程休眠。
被锁住的对象在执行notify之后唤醒阻塞队列中某线程,被唤醒的线程进入就绪队列,等待获得锁。
因为是队列,所以只会唤醒一个阻塞线程。
被唤醒的线程获得锁之后,从上次的代码处继续执行。

建立三个线程,A线程打印10次A,B线程打印10次B,C线程打印10次C,要求线程同时运行,交替打印10次ABC。这个问题用Object的wait(),notify()就可以很方便的解决。代码如下

public class MyThreadPrinter2 implements Runnable {      
    private String name;     
    private Object prev;     
    private Object self;     

    private MyThreadPrinter2(String name, Object prev, Object self) {     
        this.name = name;     
        this.prev = prev;     
        this.self = self;     
    }     

    @Override    
    public void run() {     
        int count = 10;     
        while (count > 0) {     
            synchronized (prev) {     
                synchronized (self) {     
                    System.out.print(name);     
                    count--;    

                    self.notify();     
                }     
                try {     
                    prev.wait();     
                } catch (InterruptedException e) {     
                    e.printStackTrace();     
                }     
            }     

        }     
    }     

    public static void main(String[] args) throws Exception 
    {     
        Object a = new Object();     
        Object b = new Object();     
        Object c = new Object();     
        MyThreadPrinter2 pa = new MyThreadPrinter2("A", c, a);     
        MyThreadPrinter2 pb = new MyThreadPrinter2("B", a, b);     
        MyThreadPrinter2 pc = new MyThreadPrinter2("C", b, c);     


        new Thread(pa).start();  
        new Thread(pb).start();  
        new Thread(pc).start();    
    }     
}    

java线程安全总结

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

mitsuhide1992

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值