多线程时,线程同步的两种方法简单介绍

在典型的卖票程序中,需要考虑多个窗口买票时的数据同步问题,对此可能需要线程同步,下面简单介绍下两种同步方法;
Demo:

public static void main(String[] args) {
        ThickesRunnable tr = new ThickesRunnable();//实现Runnable接口
        Thread t1 = new Thread(tr,"线程1");
        Thread t2 = new Thread(tr,"线程2");
        Thread t3 = new Thread(tr,"线程3");
        t1.start();
        t2.start();
        t3.start();
    }

ThickesRunnable 类(没有采用线程同步机制时的run()方法↓):

public class ThickesRunnable implements Runnable {
    private int thickes = 100;
    @Override
    //**************************************
    //并发访问的程序块在run()方法中↓
    public void run() {
        while(thickes > 0) {
            try {
                Thread.sleep(10);//线程休眠10ms
            } catch (InterruptedException e) {      
                e.printStackTrace();        
                }       System.out.println(Thread.currentThread().getName()+"---"+thickes--);
        }
    }
    //**************************************
}

上述这种方式,有一些弊端,比如,同一个票号会买多两张,还比如到最后票卖完时,会出现负数票号的,这些都是因为几个线程同时访问run()方法中的代码块儿,数据不同步造成的结果;


那么,java提供有线程同步机制,关键字synchronized
方式1:同步代码块

//**************************************
    //并发访问的程序块在run()方法中↓
    public void run() {
    synchronized (obj){//注意,括号中必须填一个对象名,随便一个对象都行,比如Object,String...
        while(thickes > 0) {
            try {
                Thread.sleep(10);//线程休眠10ms
            } catch (InterruptedException e) {      
                e.printStackTrace();
            }       System.out.println(Thread.currentThread().getName()+"---"+thickes--);
        }
        }
    }
    //**************************************

这种方式,是用synchronized(对象名){ }将要锁住的代码包裹起来,这样在多个线程同时访问这块儿代码时,就是调用java虚拟机的线程同步机制,来锁住,使同时只能有一个线程来访问此块儿代码;


方式2:同步方法

//**************************************
    //并发访问的程序块在run()方法中↓
    public void run() {
        method();//调用同步方法
    }
    //**************************************

同步方法:

public synchronized void method(){
    while(thickes > 0) {
            try {
                Thread.sleep(10);//线程休眠10ms
            } catch (InterruptedException e) {      
                e.printStackTrace();
            }       System.out.println(Thread.currentThread().getName()+"---"+thickes--);
        }
}

或者同步方法加static修饰:

public static synchronized void method(){
    while(thickes > 0) {//这里thickes定义时也要用static修饰了,因为此方法为静态方法
            try {
                Thread.sleep(10);//线程休眠10ms
            } catch (InterruptedException e) {      
                e.printStackTrace();
        }       System.out.println(Thread.currentThread().getName()+"---"+thickes--);
        }
}

上述两种方式可以实现java程序的线程同步,数据安全,相应的,线程同步数据安全了,那么程序执行效率就要下降了。

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值