线程同步

实现线程同步有三种方法:

  •  同步代码块

  •  同步方法

  •  Lock锁

以下用这三种方法模拟三个线程来卖票,实现共享票源

同步代码块:

package com.hucm.runnable;

public class RunSynImpl implements Runnable {

    private int ticket = 100;   //多线程共享的票源

    Object obj = new Object();  //创建一个锁对象

    @Override                   //设置线程任务卖票
    public void run() {

        while(true){
            synchronized (obj){  //同步代码块 此处也可以写【this】
                if (ticket > 0){
                    try {
                        Thread.sleep(10);  //提高程序安全问题,让程序睡眠10ms
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    System.out.println(Thread.currentThread().getName() + "-->正在卖第" + ticket + "张票");
                    ticket--;
                }
            }
        }
    }
}

同步方法:

package com.hucm.runnable;

public class RunSynFunImpl implements Runnable{

    private int ticket = 100;

    @Override
    public void run() {
        while(true){
            payTicket();
        }

    }

    /*
    * 定义一个同步方法,同步方法也会把方法内部的代码锁住
    * 只让一个线程执行
    *
    * 同步方法的锁对象也就是实现类对象
    *
    * */
    public synchronized void payTicket(){

        if (ticket > 0) {
            try {
                Thread.sleep(10);  //提高程序安全问题,让程序睡眠10ms
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println(Thread.currentThread().getName() + "-->正在卖第" + ticket + "张票");
            ticket--;
        }

    }
}

同步静态方法:

package com.hucm.runnable;

public class RunSynStaticImpl implements Runnable{

    private  static  int ticket = 100;
    @Override
    public void run() {
        while(true){
            payTicketStatic();
        }

    }

    /*
    *
    * 静态同步方法,他的锁对象【不是】this
    * 因为this是创建对象之后产生,静态方法优先于对象
    * 静态方法的锁对象是本类的class属性,即class文件对象(反射)
    *
    * */

    public static void payTicketStatic(){
        synchronized (RunSynStaticImpl.class){  //同步代码块 此处【不】可以写【this】
            if (ticket > 0){
                try {
                    Thread.sleep(10);  //提高程序安全问题,让程序睡眠10ms
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println(Thread.currentThread().getName() + "-->正在卖第" + ticket + "张票");
                ticket--;
            }
        }
    }
}

Lock锁:

package com.hucm.runnable;

import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

public class RunLockImpl implements Runnable{

    private int ticket = 100;   //多线程共享的票源

    Lock lock = new ReentrantLock(); //创建一个ReentrantLock对象

    @Override                   //设置线程任务卖票
    public void run() {

        while(true){
            lock.lock();      //有可能出现安全问题代码【前】调用Lock接口中的lock方法
                if (ticket > 0){
                    try {
                        Thread.sleep(10);  //提高程序安全问题,让程序睡眠10ms
                        System.out.println(Thread.currentThread().getName() + "-->正在卖第" + ticket + "张票");
                        ticket--;
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }finally {
                        lock.unlock(); //有可能出现安全问题代码【后】调用Lock接口中的unlock方法
                    }
                }
        }
    }
}

测试以上四种方法的测试类:

package com.hucm.runnable;

public class TestMain {

     //创建三个线程同时开启,对共享的票进行出售
     public static void main(String[] args) {

         /*
         * 创建了一个实现类,传到三个线程里面,为了保证票就是100张
         *让三个线程来卖票,实现共享票源
         * 如果创建了三个实现类,那么票就是300张,那就自个玩自个的
         * */

         // RunSynImpl run = new RunSynImpl();            //同步代码块
         //RunSynFunImpl run = new RunSynFunImpl();       //同步方法
         //RunSynStaticImpl run = new RunSynStaticImpl(); //静态同步方法
         RunLockImpl run = new RunLockImpl();             //Lock锁
         Thread t0 = new Thread(run);
         Thread t1 = new Thread(run);
         Thread t2 = new Thread(run);

         //开启多线程
         t0.start();
         t1.start();
         t2.start();
     }
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值