线程同步----synchronized

本文深入探讨了多线程环境下同步问题的重要性,并详细解释了如何通过同步代码块和同步方法来解决线程安全问题。同时,文章还介绍了wait()、notify()、notifyAll()方法的作用以及它们在多线程编程中的应用。最后,通过实例演示了如何在实际项目中应用这些概念。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一、在用多线程实现火车票系统时,当一个线程执行Thread.sleep(10);后,会有另一个线程进入到代码当中,这样就会不安全,所以在一个线程睡眠时为了防止另一个线程进入到该代码使用线程同步。

  1. 每一个对象都有一个监视器,或者叫做锁。
  2. 同步方法利用的是this所代表的对象的锁。
  3. 每个class也有一个锁,是这个class所对应的Class对象的锁。
二、实现同步的两种方式:
  1. 同步代码块,在需要同步的一段代码当中使用synchronized(任何对象)如:
  • Object obj = new Object();
  • synchronized(obj){    执行代码;    }
-----在一个线程进入执行代码段时,不允许别的线程进入,除非该线程执行完代码
  • synchronized(this){    执行代码;    }
-----如果同步方法和同步代码块需要保持一致,则两者都对this进行同步
  1. 同步方法,在需要同步的方法前使用synchronized关键字,如:
  • public synchronized void sell(){ 执行代码  }
-----同步方法对this进行加琐

注:线程的死锁:线程1锁住了对象A的监视器,等待对象B的监视器,线程2锁住了对象B的监视器,等待对象A的监视器,就造成了死锁。

三、wait()、notify()、notifyAll(),三个方法应在同步方法或同步块当中调用
  1. 每一个对象除了有一个锁之外,还有一个等待队列(wait set),当一个对象刚创建的时候,它的对待队列是空的。
  2. 我们应该在当前线程锁住对象的锁后,去调用该对象的wait方法。会产生异常。
  3. 当调用对象的notify方法时,将从该对象的等待队列中删除一个任意选择的线程,这个线程将再次成为可运行的线程。
  4. 当调用对象的notifyAll方法时,将从该对象的等待队列中删除所有等待的线程,这些线程将成为可运行的线程。

四、实例

  • class Try
  • {
  • public static void main(String [] args){
  • Queue q = new Queue();
  • Producer p = new Producer(q);
  • Consumer c = new Consumer(q);
  • p.start();
  • c.start();
  • }
  • }


  • class Producer extends Thread{
  • Queue q;
  • Producer(Queue q){
  • this.q = q;
  • }
  • public void run(){
  • for(int i=0;i<10;i++){
  • q.put(i);
  • System.out.println("Producer put:"+i);
  • }
  • }
  • }


  • class Consumer extends Thread{
  • Queue q;
  • Consumer(Queue q){
  • this.q = q;
  • }
  • public void run(){
  • while(true){
  • System.out.println("Consumer get:"+q.get());
  • }
  • }
  • }


  • class Queue{
  • int value;
  • boolean bFull = false;
  • public synchronized void put(int i){
  • if(!bFull){
  • value = i;
  • bFull = true;
  • notify();
  • }
  • try{
  • wait();
  • }catch(Exception ex){
  • ex.printStackTrace();
  • }
  • }
  • public synchronized int get(){
  • if(!bFull){
  • try{
  • wait();
  • }catch(Exception e){
  • e.printStackTrace();
  • }
  • }
  • bFull = false;
  • notify();
  • return value;
  • }
  • }




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值