指定关键字 网站有更新就提醒,杭州北京网站建设公司,广州古柏广告策划有限公司,做网站详细步骤“多线程”#xff1a;并发
要介绍线程#xff0c;首先要区分开程序、进程和线程这三者的区别。
程序#xff1a;具有一定功能的代码的集合#xff0c;但是是静态的#xff0c;没有启动运行 进程#xff1a;启动运行的程序【资源的分配单位】 线程#xff1a;进程中的…“多线程”并发
要介绍线程首先要区分开程序、进程和线程这三者的区别。
程序具有一定功能的代码的集合但是是静态的没有启动运行 进程启动运行的程序【资源的分配单位】 线程进程中的每一条执行路径就是线程。
概念 并行多个CPU同时执行多个任务 并发一个CPU“同时”执行多个任务采用时间片切换
将1分钟---分成10000份6毫秒
5.1使用线程的3种方式
第一种方式继承父类
1.创建线程类 public class NumberThread extends Thread 2.创建线程对象【新生状态】 NumberThread numnew NumberThread(); 3.【就绪状态】---cpu给资源---运行状态 num.start(); 如果调用run()则不是多线程的了会直接执行完
例子售票窗口 有10张车票3个窗口同时售票显示售票结果。
package thread; public class WindowThread extends Thread { static int ticket10; public WindowThread() { } public WindowThread(String name) { super(name); } Override public void run() { while (ticket 1) { System.out.println(getName()窗口卖出第ticket票); ticket--; } }
}package thread; public class TestMain { public static void main(String[] args) { WindowThread w1new WindowThread(第1); w1.start(); WindowThread w2new WindowThread(第2); w2.start(); WindowThread w3new WindowThread(第3); w3.start(); }
}优点启动线程对象高效率 缺点占用了父类位置
第二种方式实现接口
public class Window implements Runnable { int ticket10; Override public void run() { while (ticket 1) { System.out.println(Thread.currentThread().getName()窗口卖出第ticket张票); ticket--; } }
}public class Test { public static void main(String[] args) { Window w1new Window(); Thread t1 new Thread(w1,第1); t1.start(); Thread t2 new Thread(w1, 第2); t2.start(); Thread t3 new Thread(w1, 第3); t3.start(); }
}优点没有占用父类位置,共享资源能力强资源不用加static 缺点启动线程对象 效率低
第三种方式实现接口
对比第一种和第二种创建线程的方式发现无论第一种继承Thread类的方式还是第二种实现Runnable接口的方式都需要有一个run方法 但是这个run方法有不足 1没有返回值 2不能抛出异常
基于上面的两个不足在JDK1.5以后出现了第三种创建线程的方式实现Callable接口
实现Callable接口好处1有返回值 2能抛出异常 缺点线程创建比较麻烦
package com.msb.test05;
import java.util.Random;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.FutureTask;
/*** author : msb-zhaoss*/
public class TestRandomNum implements CallableInteger {/*1.实现Callable接口可以不带泛型如果不带泛型那么call方式的返回值就是Object类型2.如果带泛型那么call的返回值就是泛型对应的类型3.从call方法看到方法有返回值可以跑出异常*/Overridepublic Integer call() throws Exception {return new Random().nextInt(10);//返回10以内的随机数}
}
class Test{//这是main方法程序的入口public static void main(String[] args) throws ExecutionException, InterruptedException {//定义一个线程对象TestRandomNum trn new TestRandomNum();FutureTask ft new FutureTask(trn);Thread t new Thread(ft);t.start();//获取线程得到的返回值Object obj ft.get();System.out.println(obj);}
}
FutureTask 是Runnable接口的一个实现类因此它可以作为参数传给Tread 用线程任务对象来接返回值这里用的是ft 注意get方法的使用位置必须在start之后 创建几个线程对象就要创建几个FutreTask而不能new两个Thread因为这样是一个对象的内容接了两遍
5.2线程对象的常用方法
a.getName()获得当前线程对象的名字 ---线程名 如果开发者使用了无参构造器程序自动设置线程名Thread-0(主线程除外) ---开发者使用有参构造器参数的值就是线程的名字。
public class NumberThread extends Thread{ public NumberThread() { } public NumberThread(String name) { super(name); } Override public void run() { //第二条执行路线的内容 for (int i 1; i 100; i) { System.out.println(super.getName()ii); //获得当前线程名 } }
}---借助num.setName(线程1)为线程名赋值
public class TestMain { //main()方法所在的线程叫主线程 public static void main(String[] args) { NumberThread numnew NumberThread(窗口1); //此时程序开启第二条路 num.start(); NumberThread num2new NumberThread(窗口2); //此时程序开启第二条路 num2.start(); for (int i 1; i 100; i) { System.out.println(Thread.currentThread().getName()ii); } }
}b.currentThread()获得当前正在运行的线程对象 针对实现接口的情况由于没有再继承Thread类因此也无法直接使用其中的方法getName(),但Thread类中有静态方法currentThread()因此可以通过这种方法获得当前运行的线程对象的信息。c.setPriority()设置线程的优先级1-10之间默认是5
Thread t2 new Thread(w1, 第2);
t2.setPriority(1); //设置线程的优先级1-10之间默认是5
t2.start();d.Thread.currentThread().stop() 过期方法不建议执行e.强行占用。当一个线程调用了join方法这个线程就会先被执行它执行结束以后才可以去执行其余的线程。
public static void main(String[] args) throws InterruptedException { NumberThread numnew NumberThread(窗口1); //此时程序开启第二条路 num.start(); for (int i 1; i 100; i) { System.out.println(Thread.currentThread().getName()ii); if (i 50) { num.join(); //强势加入num运行完了后其余的才能执行System.out.println(maini50); } }
}f.setDaemon(true);伴随线程 tt.setDaemon(true);//设置伴随线程 主线程死亡伴随线程也会跟着一起死亡。
public class TestThread extends Thread {Overridepublic void run() {for (int i 1; i 1000 ; i) {System.out.println(子线程----i);}}
}
class Test{//这是main方法程序的入口public static void main(String[] args) {//创建并启动子线程TestThread tt new TestThread();tt.setDaemon(true);//设置伴随线程 注意先设置再启动tt.start();//主线程中还要输出1-10的数字for (int i 1; i 10 ; i) {System.out.println(main---i);}}
}g.sleep(毫秒)设置线程休眠
public static void main(String[] args) throws InterruptedException { System.out.println(1111); Thread.sleep(1000); //休眠的例子System.out.println(222);
}5.3线程的生命周期
使用线程构造器---创建线程对象---线程新生状态 创建线程对象.start()---进入到就绪状态【有资格没资源】 线程对象.run()---进入到运行状态【有资格有资源】 在时间片段内执行完---死亡状态 在时间片段内没执行完---重回就绪状态 在时间片段内出现突发事件---阻塞状态---就绪状态 5.4解决线程安全问题
【第一种同步代码块】
public void run() { while (true) { synchronized (WindowThread.class){ //WindowThread.class是监视器对象 if(ticket 1) { System.out.println(getName() 窗口卖出第 ticket 票); ticket--; } } }
}总结 同步监视器总结 1认识同步监视器锁子 ----- synchronized(同步监视器){ } 1)必须是引用数据类型不能是基本数据类型 2)也可以创建一个专门的同步监视器没有任何业务含义 3)一般使用共享资源做同步监视器即可 4)在同步代码块中不能改变同步监视器对象的引用 5)尽量不要String和包装类Integer做同步监视器 6)建议使用final修饰同步监视器
2同步代码块的执行过程 1)第一个线程来到同步代码块发现同步监视器open状态需要close,然后执行其中的代码 2)第一个线程执行过程中发生了线程切换阻塞 就绪第一个线程失去了cpu但是没有开锁open 3)第二个线程获取了cpu来到了同步代码块发现同步监视器close状态无法执行其中的代码第二个线程也进入阻塞状态 4)第一个线程再次获取CPU,接着执行后续的代码同步代码块执行完毕释放锁open 5)第二个线程也再次获取cpu来到了同步代码块发现同步监视器open状态拿到锁并且上锁由阻塞状态进入就绪状态再进入运行状态重复第一个线程的处理过程加锁 强调同步代码块中能发生CPU的切换吗能 但是后续的被执行的线程也无法执行同步代码块因为锁仍旧close
3其他 1)多个代码块使用了同一个同步监视器锁锁住一个代码块的同时也锁住所有使用该锁的所有代码块其他线程无法访问其中的任何一个代码块 2)多个代码块使用了同一个同步监视器锁锁住一个代码块的同时也锁住所有使用该锁的所有代码块 但是没有锁住使用其他同步监视器的代码块其他线程有机会访问其他同步监视器的代码块
【第二种同步方法】
public class WindowThread extends Thread { static int ticket 300; public WindowThread() { } public WindowThread(String name) { super(name); }
Override
public void run() { while (true) { if (ticket 0) { break; } else { buyTicket(); } }
} public static synchronized void buyTicket(){
//如果只有synchronized锁住的只是当前this对象相当于每一个都有300张票
//如果加了static锁住的就是方法。if(ticket 1) { System.out.println(Thread.currentThread().getName() 窗口卖出第 ticket 票); ticket--; } }
}总结 1 多线程在争抢资源就要实现线程的同步就要进行加锁并且这个锁必须是共享的必须是唯一的。 咱们的锁一般都是引用数据类型的。 目的解决了线程安全问题。
2关于同步方法
不要将run()定义为同步方法非静态同步方法的同步监视器是this 静态同步方法的同步监视器是 类名.class 字节码信息对象同步代码块的效率要高于同步方法 原因同步方法是将线程挡在了方法的外部而同步代码块锁将线程挡在了代码块的外部但是却是方法的内部同步方法的锁是this一旦锁住一个方法就锁住了所有的同步方法同步代码块只是锁住使用该同步监视器的代码块而没有锁住使用其他监视器的代码块 【第三种方式Lock锁】
Override //Lock锁
public void run() { Lock lock new ReentrantLock(); //创建Lock锁对象 while (true) { lock.lock();//上锁 if (ticket 1) { System.out.println(getName() 窗口卖出第 ticket 票); ticket--; } lock.unlock(); //解锁 if (ticket 0) { break; } }
}5.5线程通信 package com.msb.test11;
/*** author : msb-zhaoss*/
public class Product {//商品类//品牌private String brand;//名字private String name;//引入一个灯true:红色 false 绿色boolean flag false;//默认情况下没有商品 让生产者先生产 然后消费者再消费//setter,getter方法public String getBrand() {return brand;}public void setBrand(String brand) {this.brand brand;}public String getName() {return name;}public void setName(String name) {this.name name;}//生产商品public synchronized void setProduct(String brand,String name){if(flag true){//灯是红色证明有商品生产者不生产等着消费者消费try {wait();} catch (InterruptedException e) {e.printStackTrace();}}//灯是绿色的就生产this.setBrand(brand);try {Thread.sleep(100);} catch (InterruptedException e) {e.printStackTrace();}this.setName(name);//将生产信息做一个打印System.out.println(生产者生产了 this.getBrand() --- this.getName());//生产完以后灯变色变成红色flag true;//告诉消费者赶紧来消费notify();}//消费商品public synchronized void getProduct(){if(!flag){//flag false没有商品等待生产者生产try {wait();} catch (InterruptedException e) {e.printStackTrace();}}//有商品消费System.out.println(消费者消费了 this.getBrand() --- this.getName());//消费完灯变色flag false;//通知生产者生产notify();}
} 文章转载自: http://www.morning.lthgy.cn.gov.cn.lthgy.cn http://www.morning.pndw.cn.gov.cn.pndw.cn http://www.morning.nllst.cn.gov.cn.nllst.cn http://www.morning.nlcw.cn.gov.cn.nlcw.cn http://www.morning.tgnwt.cn.gov.cn.tgnwt.cn http://www.morning.smggx.cn.gov.cn.smggx.cn http://www.morning.syznh.cn.gov.cn.syznh.cn http://www.morning.lthtp.cn.gov.cn.lthtp.cn http://www.morning.nytgk.cn.gov.cn.nytgk.cn http://www.morning.wfhnz.cn.gov.cn.wfhnz.cn http://www.morning.msxhb.cn.gov.cn.msxhb.cn http://www.morning.qnzld.cn.gov.cn.qnzld.cn http://www.morning.rzysq.cn.gov.cn.rzysq.cn http://www.morning.mnsmb.cn.gov.cn.mnsmb.cn http://www.morning.lpmjr.cn.gov.cn.lpmjr.cn http://www.morning.tdttz.cn.gov.cn.tdttz.cn http://www.morning.ybmp.cn.gov.cn.ybmp.cn http://www.morning.lfmwt.cn.gov.cn.lfmwt.cn http://www.morning.rxkq.cn.gov.cn.rxkq.cn http://www.morning.rymd.cn.gov.cn.rymd.cn http://www.morning.xtyyg.cn.gov.cn.xtyyg.cn http://www.morning.gskzy.cn.gov.cn.gskzy.cn http://www.morning.dmlgq.cn.gov.cn.dmlgq.cn http://www.morning.dmzfz.cn.gov.cn.dmzfz.cn http://www.morning.rstrc.cn.gov.cn.rstrc.cn http://www.morning.btlsb.cn.gov.cn.btlsb.cn http://www.morning.dnconr.cn.gov.cn.dnconr.cn http://www.morning.qdbcd.cn.gov.cn.qdbcd.cn http://www.morning.crxdn.cn.gov.cn.crxdn.cn http://www.morning.mzhhr.cn.gov.cn.mzhhr.cn http://www.morning.hrpmt.cn.gov.cn.hrpmt.cn http://www.morning.wrtbx.cn.gov.cn.wrtbx.cn http://www.morning.mxlmn.cn.gov.cn.mxlmn.cn http://www.morning.qhrlb.cn.gov.cn.qhrlb.cn http://www.morning.zlcsz.cn.gov.cn.zlcsz.cn http://www.morning.kngqd.cn.gov.cn.kngqd.cn http://www.morning.fjfjm.cn.gov.cn.fjfjm.cn http://www.morning.dgng.cn.gov.cn.dgng.cn http://www.morning.kzbpx.cn.gov.cn.kzbpx.cn http://www.morning.hgfxg.cn.gov.cn.hgfxg.cn http://www.morning.qnqt.cn.gov.cn.qnqt.cn http://www.morning.wjdgx.cn.gov.cn.wjdgx.cn http://www.morning.sflnx.cn.gov.cn.sflnx.cn http://www.morning.zsleyuan.cn.gov.cn.zsleyuan.cn http://www.morning.cjmmn.cn.gov.cn.cjmmn.cn http://www.morning.gnbtp.cn.gov.cn.gnbtp.cn http://www.morning.jggr.cn.gov.cn.jggr.cn http://www.morning.brrxz.cn.gov.cn.brrxz.cn http://www.morning.rcww.cn.gov.cn.rcww.cn http://www.morning.junyaod.com.gov.cn.junyaod.com http://www.morning.dwmtk.cn.gov.cn.dwmtk.cn http://www.morning.hxxzp.cn.gov.cn.hxxzp.cn http://www.morning.fmqng.cn.gov.cn.fmqng.cn http://www.morning.xjnjb.cn.gov.cn.xjnjb.cn http://www.morning.ztdlp.cn.gov.cn.ztdlp.cn http://www.morning.rykn.cn.gov.cn.rykn.cn http://www.morning.nqyzg.cn.gov.cn.nqyzg.cn http://www.morning.ogzjf.cn.gov.cn.ogzjf.cn http://www.morning.fnmtc.cn.gov.cn.fnmtc.cn http://www.morning.rwrn.cn.gov.cn.rwrn.cn http://www.morning.rfqk.cn.gov.cn.rfqk.cn http://www.morning.yzygj.cn.gov.cn.yzygj.cn http://www.morning.gczzm.cn.gov.cn.gczzm.cn http://www.morning.pumali.com.gov.cn.pumali.com http://www.morning.ymmjx.cn.gov.cn.ymmjx.cn http://www.morning.sfwd.cn.gov.cn.sfwd.cn http://www.morning.mpmtz.cn.gov.cn.mpmtz.cn http://www.morning.bftqc.cn.gov.cn.bftqc.cn http://www.morning.supera.com.cn.gov.cn.supera.com.cn http://www.morning.fmqw.cn.gov.cn.fmqw.cn http://www.morning.ymwny.cn.gov.cn.ymwny.cn http://www.morning.zmpqt.cn.gov.cn.zmpqt.cn http://www.morning.mnsmb.cn.gov.cn.mnsmb.cn http://www.morning.pjyrl.cn.gov.cn.pjyrl.cn http://www.morning.rtlg.cn.gov.cn.rtlg.cn http://www.morning.kwqqs.cn.gov.cn.kwqqs.cn http://www.morning.prhfc.cn.gov.cn.prhfc.cn http://www.morning.brkc.cn.gov.cn.brkc.cn http://www.morning.bsrqy.cn.gov.cn.bsrqy.cn http://www.morning.lxcwh.cn.gov.cn.lxcwh.cn