java多线程

来源:互联网 发布:软件开发合同 性质 编辑:程序博客网 时间:2024/06/05 00:12
1.线程与进程
i. 进程 : 执行中的程序
1. 一个进程可以包含有一个或者多个线程
2. 一个进程至少包含一个线程
ii. 线程 :程序的单独的    执行路径
1. 单线程 : 程序中只存在一条执行路径,实际上主方法就是主线程,单线程
2.  多线程 :在一个程序中存在多条执行路径,运行多个任务,其目的是更好的利用CPU资源
2. 线程的实现

i. 继承Thread类,复写run()方法

package com.mytest;public class TestThread {public static void main(String[] args) {ThreadOne one = new ThreadOne();one.start();}}class ThreadOne extends Thread{@Overridepublic void run() {for(int i = 0 ; i<= 10 ; i++){System.out.println("thread : "+ new Thread().getName());}}}

ii. 实现Runnable接口,实现run()方法

package com.mytest;public class TestRunnable implements Runnable {public void run() {for (int i = 0; i <= 10; i++)System.out.println("第" + i + "次Runnable");}public static void main(String[] args) {TestRunnable runnable = new TestRunnable();//创建一个线程Thread thread = new Thread(runnable);thread.start();}}

iii.通过start()方法
 
3. 线程的状态
 

 
 
4. 线程常用方法
i.  isAlive(): 判断线程是否活着,即线程是否还未终止
ii.  getPriority():获取线程的优先级数值
iii. SetPriority ():设置线程的优先级数值
iv. Thread.sleep():设置线程睡眠的时间
v.  Join():调用某线程的该方法,将当前线程与该线程“合并”,即等待该线程结束,再恢复当前线程的运行
vi. Yeild() :让出CPU,当前的线程进入队列等待状态
vii.  Wait(): 当前线程进入对象的wait pool

viii.Notity()/notityAll():唤醒对象的wait pool中的一个线程或多个等待线程

package com.mytest;public class TestMethod implements Runnable{public void run() {for(int i = 0 ; i<= 5 ; i++)System.out.println("第"+i+new Thread().getName());}public static void main(String[] args) {//创建线程TestMethod isAlive = new TestMethod();Thread thread = new Thread(isAlive);thread.start();//主线程for(int i = 0 ; i <= 10 ; i++){System.out.println(thread.isAlive());if(i==8){try {Thread.sleep(1000);thread.join();} catch (InterruptedException e) {e.printStackTrace();}}}}}

 
5.同步与死锁 :synchronized只能标记非抽象的方法,不能标识成员变量
i. 避免抢占资源 :把竞争访问的资源标识为private
ii. 同步方法即同步对象
iii.同步代码块
注意:在使用synchronized关键字时候,应该尽可能避免在synchronized方法或synchronized块中使用sleep或者yield方法,因为synchronized程序块占有着对象锁,你休息那么其他的线程只能一边等着你醒来执行完了才能执行。不但严重影响效率,也不合逻辑
 
例如:同时去操作一个银行账号
 
package com.mytest;public class TestSync {public static void main(String[] args) {User u = new User(100, "zhang");MyThread myThread1 = new MyThread("线程A", u, 20);MyThread myThread2 = new MyThread("线程B", u, -20);MyThread myThread3 = new MyThread("线程C", u, 90);MyThread myThread4 = new MyThread("线程D", u, 10);//启动线程myThread1.start();myThread2.start();myThread3.start();myThread4.start();}}//线程class MyThread extends Thread{private User u;private int y = 0;public MyThread(String name , User u , int y) {super(name);this.u = u;this.y = y;}public void run() {//调用操作方法u.oper(y);System.out.println("===========");u.oper2(y);}}//一个实体类class User{private int cash;private String code;public User(int cash , String code) {this.cash = cash;this.code = code;}public void setCash(int cash) {this.cash = cash;}public void setCode(String code) {this.code = code;}//公共资源操作同步方法public synchronized void oper(int x){try {Thread.sleep(1000);this.cash += x;System.out.println(Thread.currentThread().getName()+"运行结束,增加"+x +",当前账户余额是"+cash);Thread.sleep(2000);} catch (InterruptedException e) {e.printStackTrace();}}//公共资源操作同步块public  void oper2(int x){try {Thread.sleep(1000);//同步块synchronized (this) {this.cash += x;System.out.println(Thread.currentThread().getName()+"运行结束,增加"+x +",当前账户余额是"+cash);}Thread.sleep(2000);} catch (InterruptedException e) {e.printStackTrace();}}@Overridepublic String toString() {return "User [cash=" + cash + ", code=" + code + "]";}}

6. 线程间通信
i. 线程经典问题:生产者和消费者问题
ii. Wait()
iii. Notity()

iv.NotityAll()

package com.mytest;public class TestComm {public static void main(String[] args) {GoDown goDown = new GoDown(30);Produce produce1 = new Produce(10, goDown);Produce produce2 = new Produce(10, goDown);Produce produce3 = new Produce(10, goDown);Produce produce4 = new Produce(10, goDown);Produce produce5 = new Produce(20, goDown);Produce produce6 = new Produce(20, goDown);Produce produce7 = new Produce(20, goDown);Produce produce8 = new Produce(20, goDown);Consume consume1 = new Consume(50, goDown);Consume consume2 = new Consume(50, goDown);Consume consume3 = new Consume(50, goDown);produce1.start();produce2.start();produce3.start();produce4.start();produce5.start();produce6.start();produce7.start();produce8.start();consume1.start();consume2.start();consume3.start();}}/** *  * @ClassName: GoDown * @Description: 仓库 * @author shanzhong.xie * @date 2015-10-30 上午09:38:14 * @version V1.0 */class GoDown {public static final int max_size = 100;public int curNum;public GoDown() {}public GoDown(int curNum) {this.curNum = curNum;}/** *  * @Title: produce * @Description: 生产方法 * @author shanzhong.xie * @date 2015-10-30 上午09:42:22 * @param needNum * @return void */public synchronized void produce(int needNum) {while (curNum + needNum > max_size) {System.out.println("要生产的产品数量" + needNum + ",超过剩余库存量"+ (max_size - curNum) + ",暂时不能执行生产任务!");try {wait();} catch (InterruptedException e) {e.printStackTrace();}}curNum += needNum;System.out.println("已经生产了" + needNum + "个产品,现仓储量为" + curNum);// 唤醒所有wait的线程,通知消费者进行消费notifyAll();}/** *  * @Title: consume * @Description: 消费方法 * @author shanzhong.xie * @date 2015-10-30 下午02:20:22 * @param needNum * @return void */public synchronized void consume(int needNum) {while (curNum < needNum) {try {wait();} catch (InterruptedException e) {e.printStackTrace();}}curNum -= needNum;System.out.println("已经消费了" + needNum + "个产品,先仓库为" + curNum);// 唤醒所有wait的线程,通知生产者进行消费notifyAll();}}/** *  * @ClassName: Produce * @Description: 生产者 * @author shanzhong.xie * @date 2015-10-30 下午02:32:46 * @version V1.0 */class Produce extends Thread {private int needNum;private GoDown goDown;public Produce(int needNum, GoDown goDown) {this.needNum = needNum;this.goDown = goDown;}public void run() {goDown.produce(needNum);}}/** *  * @ClassName: Consume * @Description: 消费者 * @author shanzhong.xie   * @date 2015-10-30 下午02:35:33 * @version V1.0 */class Consume extends Thread {private int needNum;private GoDown goDown;public Consume(int needNum , GoDown goDown) {this.needNum = needNum;this.goDown = goDown;}public void run() {goDown.consume(needNum);}}


1 0