线程的同步和死锁2

2019-01-24  本文已影响0人  秋笙fine

本篇是为了同步处理操作。

通过观察可以发现,以上程序所带来的最大问题在:判断和修改数据是分开执行的,即某几个线程可以同时进行这些功能。

然而我们要实现卖票功能,判断和修改数据应该要由单个线程执行完,别的线程才能进行之后的操作,因而要加锁。

在Java里面如果想要实现线程同步,可以使用synchronized关键字来加锁。而这个关键字可以通过两种方式使用。

1.同步代码块(同步块必须锁定一个对象,一般就是锁当前对象)
2.同步方法

范例:观察同步块

package TestDemo;



class MyThread implements Runnable{//Runnable接口子类,也是线程公有对象,其实例化对象在堆中

    private int ticket=5;

    @Override
    public void run() {
        for (int i = 0; i < 20; i++) {
            synchronized(this){//当前操作每次只允许一个对象进入
            if(this.ticket>0){
                try {
                    Thread.sleep(100);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            
            System.out.println(Thread.currentThread().getName()+",sell ticket="+this.ticket--);
            
            }
        }
    }
    }   
}

public class TestDemo{
    
    public static void main(String[] args)throws Exception{
        MyThread mt=new MyThread();
    
        new Thread(mt,"seller A").start();
        new Thread(mt,"seller B").start();
        new Thread(mt,"seller C").start();
        new Thread(mt,"seller D").start();


    }
    
}

结果:


image.png

成功了。

范例:观察同步方法

package TestDemo;



class MyThread implements Runnable{//Runnable接口子类,也是线程公有对象,其实例化对象在堆中

    private int ticket=5;

    @Override
    public void run() {
        for (int i = 0; i < 20; i++) {
                this.sale();//调用同步方法
            }
    }

    public synchronized void sale(){//同步方法
        if(this.ticket>0){
            try {
                Thread.sleep(100);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        
        System.out.println(Thread.currentThread().getName()+",sell ticket="+this.ticket--);
        
        }
    }

        
        
}

public class TestDemo{
    
    public static void main(String[] args)throws Exception{
        MyThread mt=new MyThread();
    
        new Thread(mt,"seller A").start();
        new Thread(mt,"seller B").start();
        new Thread(mt,"seller C").start();
        new Thread(mt,"seller D").start();


    }
    
}

结果:


image.png

也实现了。

中间件会帮我们实现一部分同步操作,没有的轮子可以自己写。同步操作与异步操作相比,异步操作的执行操作快,但是同步操作的线程安全性高。

上一篇 下一篇

猜你喜欢

热点阅读