线程同步

本文介绍了多线程中的同步概念,强调了同步对于避免并发安全问题的重要性。同步可以通过synchronized关键字实现,包括同步方法和同步块。此外,还提到了wait、notify和notifyAll方法在控制线程间交互的作用。需要注意线程同步时锁对象的一致性以及wait和notify的正确使用。

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

线程同步
同步是多线程中的重要概念。同步的使用可以保证在多线程运行的环境中,程序不会产生设计之外的错误结果。同步的实现方式有两种,同步方法和同步块,这两种方式都要用到synchronized关键字。

局部内部类中,若要引用从属的局部变量,那么这个变量必须是final的

1、同步方法
多个线程并发读写同一个临界资源时会发生“线程并发安全问题”
常见的临界资源

  • 多线程共享实例变量
  • 多线程共享静态公共变量

解决办法

异步操作:多线程并发操作,相当于个干各的。
同步操作:有先后顺序的操作,相当于你干完我再干。
sychronized关键字
synchronized关键字是java中的同步锁。 由于java的每个对象都有一个内置锁,当用此关键字修饰方法时, 内置锁会保护整个方法。在调用该方法前,需要获得内置锁,否则就处于阻塞状态。

注: synchronized关键字也可以修饰静态方法,此时如果调用该静态方法,将会锁住整个类。package com.xhj.thread;

/**
 * 线程同步的运用
 * 
 * @author XIEHEJUN
 * 
 */
public class SynchronizedThread {

    class Bank {
        private int account = 100;
        public int getAccount() {
            return account;
        }

        /**
         * 用同步方法实现
         * 
         * @param money
         */
        public synchronized void save(int money) {
            account += money;
        }

        /**
         * 用同步代码块实现
         * 
         * @param money
         */
        public void save1(int money) {
            synchronized (this) {
                account += money;
            }
        }
    }
这里写代码片

2、  即有synchronized关键字修饰的语句块。 被该关键字修饰的语句块会自动被加上内置锁,从而实现同步
代码如:

    synchronized(object){ 
    }

3、wait与notify

wait():使一个线程处于等待状态,并且释放所持有的对象的lock。

sleep():使一个正在运行的线程处于睡眠状态,是一个静态方法,调用此方法要捕捉InterruptedException异常。
notify():唤醒一个处于等待状态的线程,注意的是在调用此方法的时候,并不能确切的唤醒某一个等待状态的线程,而是由JVM确定唤醒哪个线程,而且不是按优先级。
Allnotity():唤醒所有处入等待状态的线程,注意并不是给所有唤醒线程一个对象的锁,而是让它们竞争。

package day04;

/**
 * 线程同步
 * 
 * @author Administrator
 *
 */
public class ThreadDemo10 {

    // 显示图片是否下载完毕
    public static boolean isFinish;
    public static Object obj = new Object();

    public static void main(String[] args) {
        // 下载线程
        Thread download = new Thread() {
            public void run() {

                for (int i = 0; i <= 100; i++) {
                    System.out.println("down:图片下载" + i + "%");
                }
                try {
                    Thread.sleep(500);
                } catch (InterruptedException e) {

                }
                System.out.println("图片下载完成!");
                isFinish = true;
                /**
                 * 当图片下载完毕,就应当通知显示图片的线程 开始工作了
                 */
                synchronized (obj) {
                    obj.notify();
                }

                for (int i = 0; i <= 100; i++) {
                    System.out.println("down:附件下载" + i + "%");
                }
                try {
                    Thread.sleep(500);
                } catch (InterruptedException e) {

                }
                System.out.println("附件下载完成!");
                isFinish = true;

            }
        };
        /**
         * main方法中定义一个内部类show, 该内部类中若想引用main方法中的其他 局部变量,那么这个变量必须是final的类型
         */
        // 显示线程
        Thread show = new Thread() {
            public void run() {
                try {
                    // 这里应该等待下载线程将图片加载完毕之后再执行
                    // download.join();
                    // 在obj上等待
                    synchronized (obj) {
                        obj.wait();
                    }
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                for (int i = 0; i <= 100; i++) {
                    System.out.println("show:图片加载" + i + "%");
                    if (!isFinish) {
                        throw new RuntimeException("图片加载失败!");
                    }
                }
                System.out.println("图片显示完成!");
            }

        };
        download.start();
        show.start();
    }

}

注意:

  • 多线程看到的锁对象必须是同一个对象,否则没有效果。
  • 如果sychronized块在某一个非静态方法中通常锁对象写的是this.
  • notify:会随机解除一个在当前对象上等待的线程
  • notifyAll:全部解除
  • 调用哪个对象的wait或notify,就应当对当前的方法加锁,锁对象是当前对象。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值