java 多线程
来源:互联网 发布:xfplay 怎么没有mac版 编辑:程序博客网 时间:2024/06/02 04:21
线程的状态:被创建(new PrimeThread())-->运行(start()) ----sleep(time)| wait()[notify() 唤醒等待的线程]----冻结-----销毁(stop()/run方法执行完毕)
创建线程的方式:实现方式,继承方式
实现方式 : 避免了多继承的弊端
同步
条件、前提:
1、必须要有两个或者两个以上的线程
2、必须是多个线程使用同一个锁
好处:解决了安全问题
弊端:多个现象需要判断锁,比较消耗资源
什么时候同步,什么时候不同步
1、明确那些代码是多线程运行代码
2、明确共享数据
3、明确多线程运行代码中那些语句是操作共享数据的
静态方法被同步使用的锁是: 该方法所在类的字节码对象
非静态方法被同步使用的锁是:this
等待唤醒机制
wait()、notify()、 notifyAll()
都使用在同步中,因为要对持有监视器(锁)的线程操作。
所以要使用在同步中,因为只有同步才具有锁。
等待和唤醒 必须是同一个锁对象调用
为什么这些操作线程的方法要定义在Object类中呢?
因为,监视器(锁)是任意对象,所以可以被任意对象调用
线程间的通信
案例需求:
一个生产者,一个消费者。生产者生产一个,消费者消费一个
传统的做法(jdk1.5之前的)
class Resource {private String name;private int count ;boolean hasVal = false;//判断是否有数据/** * 模拟生产方法 * @param name */public synchronized void set(String name){while(hasVal)///当醒来的时候 还要判断 是不是已经有数据 try {this.wait();} catch (Exception e) {}//如果判断 生产的东西已经被消费了,就继续生产System.out.println(Thread.currentThread().getName()+"生产者---------"+ this.count);this.name = name +"---" + count++;this.hasVal = true;this.notifyAll();}/** * 模拟消费方法 */public synchronized void out(){while(!hasVal) //当醒来的时候 还要判断 是不是已经有数据 try {this.wait();} catch (Exception e) {}//如果有数据(代表已经生产了一个) 就打印出来this.hasVal = false;this.notifyAll();System.out.println(Thread.currentThread().getName()+"消费者---------"+ this.name);}} //生产 的类class Producer implements Runnable{private Resource res;Producer (Resource res){this.res = res;}@Overridepublic void run() {while(true)res.set("苹果");}}//消费类class Customer implements Runnable{private Resource res;Customer (Resource res){this.res = res;}@Overridepublic void run() {while(true)res.out();}}
新做法--推荐(jdk1.5之后)
需求还是一样,思想也还是一样
class Resource1 {private String name ;private String sex;private boolean flag = false;//判断是否有数据private final Lock lock = new ReentrantLock();//Condition 可以理解为 同步的对象锁(以前是用 Object对象)private final Condition cond_pro = lock.newCondition();private final Condition cond_cus = lock.newCondition();public void set(String name ,String sex) throws InterruptedException{lock.lock();///此处是关键部分, 使用了面向对象的方式try {while(flag){cond_pro.await();}//让生产线程等待this.name = name;this.sex = sex;this.flag = true;cond_cus.signalAll();//唤醒 消费线程} finally {lock.unlock();//此处是关键部分,关闭锁资源}}public void out () throws InterruptedException{lock.lock();try {while(!flag){cond_cus.await();}System.out.println(this.name+"***"+this.sex);this.flag = false;cond_pro.signalAll();} finally {lock.unlock();}}}
停止线程
在jdk1.5之后,就没有提供 ,手动停止线程的方法。所以停止线程的方法唯一方法就是: 让run方法执行完毕
而在大多数run方法中都使用了循环,所以只要控制循环就可以控制线程了。
特殊情况:
在被同步的run方法中,或者 run方法中的一个同步方法 中 使用了wait()方法,而同步代码块中也没有唤醒当前锁的方法是,线程就会一直处于 冻结状态,此时可以使用Thread.interrupt()方法来唤醒处于冻结状态的线程,让他们有执行线程的资格,
class StopThreadSync implements Runnable{private boolean flag = true;@Overridepublic synchronized void run() {while(flag){try {///处于冻结状态,放弃了执行资格 ,而且没有 锁 来唤醒当前线程wait();} catch (InterruptedException e) {System.out.println("interrupt Exception");//当打断 处于冻结状态的 线程(此时当前线程 有了执行资格),会抛出异常 ,//flag =false;}System.out.println("Thread Runing...");}}public void stopWhile (){this.flag = false;}}
守护线程
Thread.setDaemon(boolean);
将该线程标记为守护线程(有点类似 后台线程),当正在运行的所有线程都是守护(后台)线程时,java虚拟机退出(即程序结束)
注意:这个方法必须在线程运行前执行
Join 等待线程
这个方法能抢夺cpu执行权,
ThreadDemo td = new ThreadDemo();///Runnble子类
Thread t1 = new Thread(td );
Thread t1 = new Thread(td );
t2.start();
////主线程会等待 t1线程执行完毕后,才开始执行,跟其他线程是否执行完毕没有关系
t1.join();
t1.start();
线程的优先级
ThreadDemo td = new ThreadDemo();///Runnble子类
Thread t1 = new Thread(td );
Thread t1 = new Thread(td );
t2.start();
////提高t1抢夺cpu执行权的频率
t1.setPriority(Thread.MAX_PRIORITY);
t1.start();
- 【Java多线程】多线程死锁
- Java 多线程
- java 多线程
- java多线程
- JAVA多线程
- java多线程
- JAVA多线程
- java多线程
- JAVA 多线程
- Java多线程
- java多线程
- JAVA 多线程
- Java 多线程
- Java 多线程
- java多线程
- Java 多线程
- Java多线程
- java 多线程
- POJ 2864 - Pascal Library
- 成为合格管理者的几个关键词
- 关于网卡和路由之类的
- Java多线程系列--“基础篇”09之 interrupt()和线程终止方式
- 新的互联网是什么样子?
- java 多线程
- Android中Yahoo天气预报API的使用
- 黑马程序员-传智播客资料中的面试题
- gcd算法整合(最大公约数)
- 浅谈外连接中的on条件字句
- 读老子,明智明理
- HTML4常用标签元素总结及简介
- Ubuntu搭建版本库svn与wensvn管理工具
- MongoDB2.6window系统下安装服务