多线程

多线程--百度百科:多线程(英语:multithreading),是指从软件或者硬件上实现多个线程并发执行的技术。具有多线程能力的计算机因有硬件支持而能够在同一时间执行多于一个线程,进而提升整体处理性能。具有这种能力的系统包括对称多处理机、多核心处理器以及芯片级多处理(Chip-level multithreading)或同时多线程(Simultaneous multithreading)处理器。 [1] 在一个程序中,这些独立运行的程序片段叫作“线程”(Thread),利用它编程的概念就叫作“多线程处理(Multithreading)”。具有多线程能力的计算机因有硬件支持而能够在同一时间执行多于一个线程(台湾译作“执行绪”),进而提升整体处理性能。 自己理解:线程是CPU处理数据的最小单位。一个程序可以使单线程也可以是多线程,如果是多线程,那么就执行的更快。 为什么多线程会执行的更快:在单位时间片中,高速运转,切换线程。 1.在单位时间时间片上只能执行一个线程 2.CPU看到内存中有很多的线程,CPU在单位时间片(时间片:很微小的时间单位)上高速切换线程执行 CPU平均给线程分配资源,多线程就分配的更多资源 创建线程: 1.extends Tread public class PlayGameThread extends Thread{ public void run() { for (int i = 0; i < 100; i++) { System.out.println("double kill..."); } } } public class MusicThread extends Thread{ public void run() { for (int i = 0; i < 100; i++) { System.out.println("摩擦。。。摩擦..."); } } } public class Test { public static void main(String[] args) { PlayGameThread pgt = new PlayGameThread(); MusicThread mt = new MusicThread(); pgt.start(); mt.start(); } } 2.implement Runnable public class TicketThread implements Runnable{ private int num = 50; public void run() { // 最终的代码 while(num>0){ System.out.println("您的票号是:"+num); num--; } } } public class Test { public static void main(String[] args) { /* * 只需要创建一个TicketThread的对象 tt * 以tt为参数来创建3个Thread对象 */ TicketThread tt = new TicketThread(); Thread t1 = new Thread(tt); Thread t2 = new Thread(tt); Thread t3 = new Thread(tt); t1.start(); t2.start(); t3.start(); } } Tread类中一些常用的方法: 1.sleep睡眠:线程类Thread当中有一个static void sleep(long millis)方法,在指定的毫秒数内让当前正在执行的线程休眠。 2.优先级:线程的优先级:每个线程[线程对象]都有一个优先级,高优先级线程的执行优先于低优先级线程(简单说:如果一个线程的优先级越高,获得CPU资源的机会更大,不等于高优先级的就最先执行)。 3.守护线程: 1)、守护线程(精灵线程/后台线程) ①每个线程都可以或不可以标记为一个守护程序 ②后台线程仅仅就是对线程的一个分类或者标记 2)、特点: ① 一般来说后台线程是为前台线程服务的(例如gc线程); ② 如果所有的前台线程都死了,那么后台线程也会自动的死亡;但是前台线程死了,后台线程不一定立即死亡(可能还需要收尸...) ③ 一个线程的默认状态和创建它的环境线程状态一致 public static void main(String[] args) { Thread t = Thread.currentThread(); System.out.println(t.isDaemon()); t.setDaemon(true);//活动状态的线程不能够修改后台线程 Thread tt = new Thread(); System.out.println(tt.isDaemon()); //tt.start();//活动的线程不能改变状态Exception in thread "main" java.lang.IllegalThreadStateException tt.setDaemon(true); System.out.println(tt.isDaemon());//自定义线程未启动可设置后台线程 } 4.join等待终止:join为线程当中的方法,某线程实例调用该方法,其他线程会等待该线程执行完毕之后在执行。 5.礼让yield:static void yield() 暂停当前正在执行的线程对象,并执行其他线程。但是不一定会一定礼让。 线程中经典的售票案例: 票池:50张。3个窗口售卖 1.票,用什么来存放票:票池 可以使用一个变量来表示票池,当卖出一个张票,该变量就自减一次 int num = 50; 2.本质就是要创建启动线程(流程) 明确需要把什么事情封装成独立的线程对象 卖(一张)票的操作 怎么操作? 判断是否有票,如果有票就卖一张 票总数减一 3.怎么实现: 自定义一个类 extends Thread类 实现功能自定义类覆写Thread类当中的run方法,实现伪代码功能 创建线程对象调用start方法启动线程 1.共享问题,用来存放票量的,变量应该如何被多个窗口共享 2.应该自定义几个类?1个类 之前游戏有不同功能,写了不同类,卖票都是一个功能,所以定义一个类就行了 3.应该创建几个对象?3个对象 三个窗口,可以创建三个对象来表示三个窗口 代码实现: ①同步代码块 synchronized (mutex) { //需要被保护的代码块 } 实例: while(num>0){//只要有票就卖 synchronized (TicketThread.class) {//同步监听,同一个对象 if(num > 0){//锁住了此流程,从synchronized进入一个就关闭,等一个结束完了,然后又打开再进入第二个 System.out.println(getName()+"还剩的票数为:"+num); num--; } } } ②同步方法 public static synchronized void saleOne(){//加上synchronized为同步监听方法,静态方法!可加可不加根据需求 if(num>0){//卖一张票的操作【业务角度各自的】 System.out.println(Thread.currentThread().getName()+":您的票号是:"+num); num--; } } ③锁机制 Lock 锁定代码块,保护代码块 Lock l = ...; l.lock(); try { // access the resource protected by this lock } finally { l.unlock(); } 实例: while(num>0){//只要有票就卖 lock.lock();//开启锁 try {//被保护的代码 if(num>0){//卖一张票的操作【业务角度各自的】 System.out.println(getName()+":您的票号是:"+num); num--; } } finally {//释放锁,让下一个进入 lock.unlock(); } } 在线程中的唤醒与等待: Bank类//账户类 public class Bank { double qian; boolean empty = true;//true为空,则没钱 void save(){ synchronized (Bank.class) {//要用同一个对象,那么就是使用同一个同步监听 if(!empty){//当为false,那么就是有钱 //等待取钱先执行,直接让synchronized中的代码先不执行,执行另一个 try {//捕捉异常 Bank.class.wait();//表示前面用的对象,现在也在使用,在同一个对象下,使用同一个同步监听, //并且等待和唤醒也是可以在同一个同步监听中可以交替进行。 } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } System.out.println("何杰存钱之前:"+qian); qian += 520;//此时为空,那么就存钱,对变量进行增 System.out.println("何杰存钱之后:"+qian); empty = false;//设置标识,当执行完存钱之后,那么现在就做一个标识,标识现在有钱 Bank.class.notify();//唤醒。使用对象去唤醒。当此程序执行完毕之后,唤醒另一个的程序 } } void get(){ synchronized (Bank.class) {//要用同一个对象,那么就是使用同一个同步监听,Bank.class为本类的对象引用 if(empty){//当为true则没钱,那么就要等待存钱执行 //等待,让存钱先执行 try { Bank.class.wait(); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } System.out.println("王雨取钱之前:"+qian); qian -= 520;//此时为false,则是有钱,有钱了然后对变量进行减 System.out.println("王雨取钱之后:"+qian); empty = true;//上面进行的是false运算,当运行完毕时,那么就更改为没钱,作为标识 Bank.class.notify(); } } } Save类//线程类 public class SaveMoney extends Thread { Bank bank; public SaveMoney(Bank bank) { this.bank = bank; } @Override public void run() { for (int i = 0; i < 20; i++) { bank.save(); } } } get类//线程类 public class GetMoney extends Thread { Bank bank; public GetMoney(Bank bank) { this.bank = bank; } @Override public void run() { for (int i = 0; i < 20; i++) { bank.get(); } } } Test类//测试类 public class Test {//测试类 public static void main(String[] args) { Bank bank = new Bank(); SaveMoney sav = new SaveMoney(bank); GetMoney get = new GetMoney(bank); sav.start(); get.start(); } } 线程的生命周期: ① 创建 ; 例如 Thread t = new Thread(); ② 就绪 ; 调用了start方法 t.start() ---> 告诉CPU我准备好了 ③ 运行 ; 获得CPU的资源,开始执行线程体中的代码 ④ 死亡 ; 有多种情况导致死亡, 1)例如线程体执行完毕(自然老死); 2)非自然死亡(异常没有处理好); 3)对象失去引用 4)对象被垃圾回收机制销毁 注意:① 休眠等操作可能导致正在运行的线程阻塞],阻塞完了(sleep完了)进入的是就绪状态,相互一一直等待,出现死锁! ② 一个线程死了就死了,不能够死而复生 线程定时任务: Timer timer = new Timer(); MyTimerTask myTimerTask = new MyTimerTask(); //安排了 一个TimerTask 子类线程任务 timer.schedule(myTimerTask, new Date(),5000); Thread.sleep(8000); timer.cancel();//取消任务

转载于:https://my.oschina.net/u/4083606/blog/3029558

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值