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();
线程进入阻塞
- 线程调用sleep()方法进入休眠状态
- 线程调用了一个阻塞时IO方法,在该方法返回之前,线程处于阻塞
- 线程试图获取一个同步锁(监视器),但是该锁正被其他线程所持有
- 线程在等待某个通知(notify)
线程离开阻塞
线程死亡
- 调用的sleep()方法时间到
- 调用的阻塞IO方法已经返回
- 成功获得到了同步锁
- 获得等待的通知
- run()方法执行完成,线程正常结束
- 线程抛出一个未捕获的Exception或Error
- 直接调用线程的stop方法(禁止使用)
- 可以使用isAlive()方法判断线程是否死亡,该方法在线程处于就绪、运行、阻塞三种状态时返回true,处于新建及死亡状态时返回false
- 线程一旦死亡,则不能再次调用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(); //解锁 } }
- Java线程:什么是线程
- Java线程:线程池
- java线程--线程退出
- JAVA-线程/线程锁
- Java线程:什么是线程
- Java线程:线程中断
- Java线程:线程状态
- Java线程: 线程调度
- Java线程:线程交互
- java--线程--线程池
- java 线程
- Java线程
- java线程
- java线程
- Java线程
- Java线程
- java线程
- JAVA 线程
- 图表绘制 HTML5
- 杭电DIY——金币游戏
- JS长整型精精度问题
- Python中else语句整理
- Sqlserver:timestamp数据类型
- Java线程
- Java多线程发展简史
- 桌面小控件appwidget的简单使用
- C++ AMP: Lambdas, auto, and static_assert: C++0x Features in VC10, Part 1
- 破解 WinHTTP 和 IESniffer 记录
- Openwrt安装软件到U盘
- Linux内核动态内存分配
- CString转换成CTime
- java.lang.OutOfMemoryError: PermGen space(MyEclipse 内存不足的解决)