Thead多线程2--线程的暂停与互斥

本文详细介绍了Java中线程的暂停使用sleep方法,包括其单位和异常处理。重点讨论了线程互斥处理的重要性,以银行账户操作为例说明数据竞争和使用synchronized关键字进行互斥控制的方法。同时区分了synchronized实例方法、静态方法以及代码块的使用场景。
摘要由CSDN通过智能技术生成

1.4 线程的暂停

线程Thread类中的sleep方法能够暂停线程运行,单位为毫秒。Sleep方法可能会抛出InterruptedException异常。

public class Main {
    public static void main(String[] args) {
        for (int i = 0; i < 10; i++) {
            System.out.print("Good!");
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {

            }
        }
    }
}

应用场景:

  1. 设计一定时间后关闭对话框
  2. 把按钮按下瞬间的状态显示给用户

在sleep方法中,停止时间也可以指定到纳秒(10^-9)单位。语法:Thread.sleep(毫秒,纳秒)。不过,通常Java平台运行无法实现这么准确的控制,具体精确程度依Java平台运行环境而不同。

1.5 线程的互斥处理

多线程中的各种程序都是自由运行的,所有它们有时会操作同一个实例,可能在某些情况下引发问题。

例如:从银行账户中取款时,余额确认部门的代码应该是下面这样。

if (可能余额大于等于取款金额){
	从余额上减掉取款金额
}

但是,如果两个线程同时执行这段代码,那么可能余额会出现负数。

在这里插入图片描述

这种线程A和线程B之间竞争互相而引起的与预期相反的情况称为数据竞争竞态条件。这时候就需要一种“交通管制”来防止发生数据竞争,这种“交通管制”操作称为互斥。Java使用关键字synchronized来执行线程的互斥。

public class Bank {
    private int money;
    private String name;

    public Bank(int money, String name) {
        this.money = money;
        this.name = name;
    }

    // 存款
    public synchronized void deposit(int m) {
        money += m;
    }

    // 取款
    public synchronized boolean withdraw(int m) {
        if (money >= m) {
            money -= m;
            return true
        } else {
            return false
        }
    }

    public String getName() {
        return name;
    }

}

一个实例中的synchronized方法每次只能由一个线程运行。当正在使用synchronized方法的线程运行完之后,便会释放锁。

线程的互斥机制成为监视。获取锁有时也叫做“拥有监视”或“持有锁”。

当前线程是否以获取某一个对象的锁可以通过Thread.holdsLock方法来确认。

synchronized代码块

如果只想让方法中的某一部分由一个线程运行,而非整个方法,则可以使用synchronized代码块。

synchronized (表达式){
    ...
}

其中“表达式”为获取锁的实例。synchronized代码块用于精确控制互斥处理的执行范围

synchronized 实例方法和 synchronized 代码块

synchronized void method(){
    ...
}

这跟下面的 synchronized 代码块包围起来的是等效的。

void method(){
	synchronized (this){
		...
	}
}

synchronized实例方法是使用this的锁来执行线程的互斥处理。

synchronized 静态方法和 synchronized 代码块

synchronized静态方法每次只能由一个线程运行。但是synchronized静态方法使用的锁和synchronized实例方法使用的锁是不一样的。

class Something {
    static synchronized void method (){
        ...
    }
}

这跟下面的synchronized代码块包围起来的是等效的。

class Something {
    static void method () {
        synchronized (Something.clss){
            ...
        }
    }
}

synchronized 静态方法是使用该类的类对象的锁来执行线程互斥的。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值