多线程
一、实现多线程的常用三种方式
-
继承Thread类+重写run方法
-
Thread类常用的两个构造方法
public Thread(String threadName){} public Thread(){}
-
实例
public calss ThreadTest extends Thread{ //继承Thread类 private int count = 10; @Override public void run(){ //重写run方法 while(true){ System.out.println(count+" "); if(--count = 0){ break; //当count自减为0,结束循环 } } } public static void main(String args[]){ new ThreadTest().start(); //实例化继承类,并启动另一个线程 } }
-
-
实现Runnable接口+run方法
-
实现Runable接口的常用语法
public class Thread extends Object implements Runnable{}
-
Thread类的实现Runnable接口的构造方法
public Thread(Runnable r) public Thread(Runnable r, String name)
-
使用接口启动新线程的步骤
- 建立Runnable对象
- 使用参数为Runnable对象的构造方法创建Thread实例
- 调用start()方法启动线程
/* *创建:实现Runable+重写run() *启动:创建实现类对象+Thread对象+start() */ public calss ThreadTest implements Runnable { //实现Runable方接口 private int count = 10; @Override public void run(){ //重写run方法 while(true){ System.out.println(count+" "); if(--count = 0){ break; //当count自减为0,结束循环 } } } public static void main(String args[]){ //创建实现类对象 ThreadTest sr = new ThreadTest(); //创建代理类对象 Thread t = new Thread(sr); //启动start() t.start(); //不保证立即运行,CPU调用 //new Thread(new ThreadTest()).start(); //实例化继承类,并启动另一个线程 } }
-
-
实现Callable接口+call方法(高并发时常用)
二、线程的生命周期
-
线程生命周期的七种状态
calss Test(){ //出生状态 new //就绪状态,启动start方法后 start(); //运行状态 runing Running //等待状态 Waiting ,必须使用notify(); notifyAll()唤醒所有等待状态的线程 wait(); //休眠状态 Timeed-Waiting; sleep(); //阻塞状态 //线程在运行状态下发出输入/输出请求,线程进入阻塞状态;输入/输出结束后线程处于运行状态 //死亡状态 blocked }
-
使线程处于就绪状态的几种方法
- 调用sleep()方法
- 调用wait()方法
- 等待输入/输出完成
-
线程处于就绪状态时,用以下方法使线程再次进入运行状态
- 线程调用notify()
- 线程调用notifyAll()
- 线程调用interrupt()
- 线程休眠时间结束
- 输入/输出结束
三、操作线程的方法
-
线程的休眠
try{ Thread.sleep(2000); //休眠2s }catch(Exception e){ e.printStackTrace(); }
-
线程的加入
-
向一个正在运行的线程A中插入一个线程B,线程A进入等待状态,等线程B执行完后再执行线程A。
//运用Thread类中的join()方法,插入线程B public class JoinTest{ private Thread threadA; //定义两个线程A,B private Thread threadB; threadA = new Thread(new Runable(){ //匿名类实现Runnable接口 int count = 0; @Override public void run(){ //重写run方法 while(true){ ++count; try{ Thread.sleep(100); //使线程A休眠100毫秒 threadB.join(); //使线程B调用join方法,是当前线程暂停执行线程B }catch(Exception e){ e.printStackTrace(); } } } }); threadA.strat(); //启动线程A threadB = new Thread(Runnable(){ int count = 0; @Override public void run(){ ++count; try{ Thread.sleep(100); }catch(Exception e){ e.printStackTrace(); } if(count==100){ break; //结束循环 } } }); threadB.start(); //启动线程B }
-
-
线程的中断(interrupt)
-
stop()已经过时,现在常使用run方法中无线循环,使用boolean类型标记控制循环的停止;
-
如果线程由于使用了wait()和sleep()进入就绪状态,可以使用Thread类中的interrupt()方法使线程离开run方法,同时结束线程;但程序会抛出中断异常,用户可以在处理异常时完成线程的中断,如终止while循环。
public class InterruptedTest implements Runnable{ private boolean isContinue = false; //设置一个标记变量,默认值为false @Override public void run(){ //重写run方法 while(true){ if(isContinue){ //当isContinue变为true时,线程停止 break; } } } public void setContinue(){ this.isContinue = true; //定义设置isContinue变量为true的方法 } }
-
使用interrupt()方法中断线程,抛出中断异常的处理实例;在异常处理是终止while循环。在项目中经常在此关闭数据库连接和关闭Socket连接。
public class interruptTest{ private Thread interrupt; //定义线程 interrupt = new Thread(new Runnable(){ int count = 0; @Override public void run(){ //重写run方法 while(true){ ++count; try{ interrupt.sleep(1000); //使线程休眠1s }catch(Interrupt e){ //捕获中断异常 System.out println("当前线程被中断"); break; } } } }); interrupt.start(); //启动线程 interrupt.interrupt(); //中断线程 }
-
-
线程的礼让
- yield()方法,他只是给当前一种提醒,告知他可以将资源礼让,但当前线程不一定会礼让;该方法使具有同样优先级的线程有进入可执行状态的机会,当当前线程放弃执行权时会再度回到就绪状态。
四、线程的优先级
- 多线程处于就绪状态时,优先级高的先执行,当优先级高的都执行完了,才执行低优先级的线程。线程的优先级可以采用setPriority()调整,若该方法设置的优先级不在1~10之内;将产生IllegalArgumentException异常。
五、线程同步
-
线程安全
线程安全问题来源于多个线程存取同一对象的数据;
-
线程同步机制
-
同步块(临界区)
- 同步机制有效防止资源冲突;同步机制使用synchronized关键字
//相当于将共享资源加了一个锁,当其他线程也访问到该数据时 public calss ThreadSafeTest implements Runnable{ int num = 10; @Override public void run(){ while(true){ synchronized(""){ //同板块 if(num>0){ try{ Thread.sleep(1000); }catch(Exception e){ e.printStackTrace(); } System.out.println("tickets"+ --num); } } } } public static void main(String[] args){ ThreadSafeTest t = new ThreadSafeTest(); Thread tA = new Thread(t); Thread tB = new Thread(t); Thread tC = new Thread(t); Thread tD = new Thread(t); tA.start(); tB.start(); tC.start(); tD.start(); } }
-
同步方法
-
同步方法就是在每个方法前用synchronized关键字修饰;
public synchronized void doit(){ //定义同步方法 if(num>0){ try{ Thread.sleep(1000); }catch(Exception e){ e.printStackTrace(); } System.out.println("tickets"+ --num); } } public void run(){ while(true){ doit(); //在run方法中调用该方法 } }
-
-