Java线程

来源:互联网 发布:淘宝上很污的买家秀 编辑:程序博客网 时间:2024/05/29 16:01

线程概念

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.javapublic 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(); } } }
//模拟取款.javapublic 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(); //解锁 } }





原创粉丝点击