Java线程

线程概念

1. 线程就是程序中单独顺序的流控制。线程本身不能运行,它只能用于程序中
2. 多线程: 单个程序中可以同时运行多个不同的线程执行不同的任务
3. 线程是程序内的顺序控制流,只能使用分配给程序的资源和环境

线程和进程

1. 一个进程可以有多个线程

2. 多个进程的内部数据和状态都是完全独立的,是不可以进行数据交换的;而多线程是共享一块内存空间和一组系统资源,有可能互相影响进程之间,可以进行数据交换,而且线程的切换比进程切换的负担要小

线程的生命周期

线程的创建

1. 继承java.lang.Thread类,并重写run()方法
2. 实现java.lang.Runnable接口,并实现其run()方法
  • 继承Thread类后,无法再继承其他类,但实现Runable()接口后还可以继承其他类
  • 实现Runable接口,访问当前线程,需要使用Thread.currentThread()方法
  • 继承Thread类,访问当前线程,使用this即可

线程的启动


//方式一 
MyThread mt = new MyThread();
mt.start();

//方式二
MyThread2 mt2 = new MyThread2();
Thread thread = new Thread(mt2);
thread.start();

线程进入阻塞

  1. 线程调用sleep()方法进入休眠状态
  2. 线程调用了一个阻塞时IO方法,在该方法返回之前,线程处于阻塞
  3. 线程试图获取一个同步锁(监视器),但是该锁正被其他线程所持有
  4. 线程在等待某个通知(notify)

线程离开阻塞

  1. 调用的sleep()方法时间到
  2. 调用的阻塞IO方法已经返回
  3. 成功获得到了同步锁
  4. 获得等待的通知

线程死亡

  1. run()方法执行完成,线程正常结束
  2. 线程抛出一个未捕获的Exception或Error
  3. 直接调用线程的stop方法(禁止使用)
  4. 可以使用isAlive()方法判断线程是否死亡,该方法在线程处于就绪、运行、阻塞三种状态时返回true,处于新建及死亡状态时返回false
  5. 线程一旦死亡,则不能再次调用start()方法让其重新执行。

join线程

Thread提供了让一个线程等待另一个线程完成的方法:join()。

当某个程序在执行过程中调用了其他线程的join()方法,则当前线程被阻塞,直到被join()方法加入的线程完成为止。

public static void main(String[] args) throws InterruptedException { 
 
	for (int i = 0; i < 20; i++) { 
	  System.out.println(Thread.currentThread().getName() +"\t" + i); 
		if(i == 5) { 
			TheThread t1 = new TheThread(); 
			t1.start(); 
			t1.join();  //开始执行t1线程
		} 
	} 
 
}


守护线程(Daemon Thread)

除了特别设置外,我们创建的线程都是非守护线程

前台线程死亡,后台线程会自动死亡

public class TheThread3 extends Thread{ 
	@Override 
	public void run() { 
		while(true) { 
			System.out.println("非守护线程"); 
		try { 
			this.sleep(1000); 
		} catch (InterruptedException e) { 
			e.printStackTrace(); 
		} 
		} 
	} 
}

public static void main(String[] args) throws InterruptedException {
 
	TheThread3 t3 = new TheThread3(); 
	t3.start(); 
	 
	for (int i = 0; i < 10; i++) { 
		System.out.println(i); 
	} 
}

//设置为守护线程: 
public static void main(String[] args) throws InterruptedException {
 
	TheThread3 t3 = new TheThread3(); 
	t3.setDaemon(true); 
	t3.start(); 
	 
	for (int i = 0; i < 10; i++) { 
		System.out.println(i); 
	} 
}

线程同步

当多个线程同时对同一个对象的实例变量进行操作时,会引起线程的同步问题!

模拟线程同步(这里用银行取款来模拟)

//User.java
public class User extends Thread{ 
 
	private Account account; 
	private String name; 
	private float money; 
	 
	public User(String name,Account account,float money) { 
		this.name = name; 
		this.account = account; 
		this.money = money; 
	} 
	 
	@Override 
	public void run() { 
		try { 
			this.sleep(2000); //等待取款时间 
		    account.getMoney(name,money); 
		} catch (InterruptedException e) { 
		    e.printStackTrace(); 
		} 
	} 
}
//模拟取款.java
public static void main(String[] args) { 

	Account account = new Account(); 
	User u1 = new User("Tom",account,1500); 
	User u2 = new User("Lucy",account,1500); 
	 
	u1.start(); 
	u2.start(); 
}
线程同步的实现方式

//1.同步方法的方式
public synchronized void getMoney(String name,float money) { 

	if(money > this.money) { 
	    System.out.println("余额不足,当前余额为:" + this.money); 
	} else { 
		this.money -= money; 
		System.out.println(name + "取款成功,当前余额为" + this.money); 
	} 
}

//2.同步代码块方式
public void getMoney(String name,float money) { 
synchronized (this) { 
	if(money > this.money) { 
	    System.out.println("余额不足,当前余额为:" + this.money); 
	} else { 
		this.money -= money; 
		System.out.println(name + "取款成功,当前余额为" + this.money); 
	} 
	} 
}
//3.同步锁(JDK>=1.5)方式
private final ReentrantLock lock = new ReentrantLock(); 
 
public void getMoney(String name,float money) { 
	lock.lock(); //加锁 
	try{ 
		if(money > this.money) { 
		    System.out.println("余额不足,当前余额为:" + this.money); 
		} else { 
			this.money -= money; 
			System.out.println(name + "取款成功,当前余额为" + this.money); 
		} 
	} finally { 
	    lock.unlock(); //解锁 
	} 
}





评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值