Java线程学习笔记(四)-线程沉睡,唤醒,连接

线程沉睡(sleep)并不会让线程释放它所持有的同步锁,而且在这期间也不会阻碍其他线程的运行。唤醒(interrupt)可以将沉睡或阻塞的线程唤醒。
线程沉睡:线程沉睡可以使当前线程沉睡一段时间,在这段时间内不会有时间片分配给线程。直到过完这段时间,线程又重新运行。
线程唤醒:线程唤醒可以使得执行了sleep操作的线程或执行了wait操作或者join操作的线程唤醒。线程沉睡要指定沉睡的时间,如果对该线程执行interrput 操作,线程可以提早继续运行,但是对于唤醒线程,单线程自己无法唤醒自己,只能等休眠结束。如果要在休眠中唤醒自己只能由另一线程唤醒自己。
线程连接:线程连接是线程间运行调度的一种操作,即线程需要等待其他线程运行结束后才能够开始,否则继续等待下去。线程连接有两种形式:join(参数)和join(),在join(参数)方法中参数表示等待的时间,单位是毫秒。若超出这个时间,则无论前面线程是否执行完毕,该线程都会继续运行。如果时间为0,则表示无期限等待。join()方法相当于join(0),表示无期限地等待。
源程序
package core;

import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;

public class TextSleepAndInterrupt extends Thread{
	private DateFormat dateFormat=new SimpleDateFormat("HH-mm-ss:SSSS");
	public void run(){
		System.out.println(dateFormat.format(new Date())+" "+getName()+" 沉睡3秒钟");
		try {
			sleep(3000);  //线程休眠3秒钟
		} catch (InterruptedException e) {//捕获唤醒异常
			System.out.println(getName()+dateFormat.format(new Date())+getName()+"唤醒异常"+e.getMessage());
		}
		interrupt();//唤醒线程,单线程自己无法唤醒自己,只能等休眠结束,可看控制台的输出时间。如果要在休眠中唤醒自己只能由另一线程唤醒自己
		System.out.println(dateFormat.format(new Date())+" 沉睡的我,是否唤醒?"+isAlive());
	}
	public void getUp(){
		Thread.currentThread().interrupt();//唤醒当前线程
		while(true){
			if(Thread.currentThread().isInterrupted()){//判断当前线程是否被唤醒
				System.out.println(dateFormat.format(new Date())+" 当前我是否被唤醒?"+Thread.currentThread().isInterrupted());
				try {
					Thread.currentThread().sleep(1); //线程休眠
				} catch (InterruptedException e) {
					System.out.println(dateFormat.format(new Date())+" "+getName()+" 唤醒异常 "+e.getMessage()+" "+Thread.currentThread().isInterrupted());
				}
				System.out.println(dateFormat.format(new Date())+" 沉睡后是否被唤醒? "+Thread.currentThread().isInterrupted());
			}
		}
	}
	public static void main(String[] args) {
		TextSleepAndInterrupt text=new TextSleepAndInterrupt();
		text.start();//启动线程
		try {
			text.join(); //线程连接 线程需要等待其他线程运行结束后才能够开始
		} catch (InterruptedException e) {//捕获唤醒异常
			e.printStackTrace();
			System.out.println(" 唤醒异常: "+e.getMessage());
		}
		text.getUp();
	}
}
运行截图

源程序解读
源代码感觉设计的有问题,这里是经过简化和整理后的代码。
(1)TextSleepAndInterrupt类继承Thread类必须要实现run()方法。在run()方法中调用Thread类的sleep()方法让线程休眠(暂停)指定的时间,如果出现异常则线程被唤醒。isAlive()方法表示线程是否是被激活,如果是激活的则返回真,否则返回假。
(2)getUp()方法通过currentThread()方法获得当前线程,interrupt()方法唤醒该线程,isInterrupted判断线程是否被唤醒。当线程被唤醒时如果调用休眠sleep()方法则会抛出唤醒异常。
(3)在main()主方法中线程的join()方法是等待前一个或几个线程运行结束后再运行getUp()方法。


  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,您的问题是关于Java线程的存钱取钱问题。这是一个经典的多线程同步问题,可以通过使用synchronized关键字来实现线程安全。下面是一个简单的示例代码: ```java public class BankAccount { private int balance; public BankAccount(int balance) { this.balance = balance; } public synchronized void deposit(int amount) { balance += amount; System.out.println("Deposit successful. Balance: " + balance); } public synchronized void withdraw(int amount) { if (balance < amount) { System.out.println("Withdraw failed. Insufficient balance."); return; } balance -= amount; System.out.println("Withdraw successful. Balance: " + balance); } } public class Main { public static void main(String[] args) { BankAccount account = new BankAccount(1000); // Create two threads to simulate deposit and withdraw Thread depositThread = new Thread(() -> { for (int i = 0; i < 5; i++) { account.deposit(100); try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } } }); Thread withdrawThread = new Thread(() -> { for (int i = 0; i < 5; i++) { account.withdraw(200); try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } } }); depositThread.start(); withdrawThread.start(); } } ``` 在这个示例代码中,我们创建了一个银行账户类BankAccount,并在其中实现了deposit和withdraw方法,并使用synchronized关键字来保证线程安全。 在main方法中,我们创建了两个线程来模拟存款和取款操作,每个线程执行5次操作。我们使用Thread.sleep方法来模拟每个操作之间的间隔,以便更好地观察多线程操作的结果。 当多个线程同时访问BankAccount对象的deposit和withdraw方法时,synchronized关键字可以确保每个方法只能被一个线程访问,从而避免了竞争条件和数据不一致的问题。 希望这个示例代码能够回答您的问题。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值