Java-多线程编程(一)
创建多线程
【Thread class】1.继承Thread类,重写run()
【Runnable接口】2.实现Runnable接口,重写run()
【*Callable接口】3.实现Callable接口——高级并发编程JUC
根据面向对象思想,少用继承,多用实现,因为Java有单继承的局限性:继承了Thread类,不得不继承其他类,就不得不重构代码。
* 执行线程必须调用start()加入到调度器中
* 不一定立即执行,系统安排调度分配执行
* 直接调用run()不是开启多线程,是普通方法调用
package com.zrl.thread; /** * 创建线程方式一 * 1.创建:继承Thread+重写run * 2.启动:创建子类对象+start * @author 16114 * */ public class StartThread extends Thread{ /** * 线程入口点 */ public void run() { for(int i=0; i<5; i++) { System.out.println("一边听歌"); } } public static void main(String[] args) { //创建子类对象 StartThread st = new StartThread(); //启动 st.start();//不保证立刻运行 cpu调用 //st.run();//普通方法的调用 for(int i=0; i<5; i++) { System.out.println("一边Coding"); } } }
package com.zrl.thread; /** * 创建线程方式二 * 1.创建:实现Runnable接口+重写run * 2.启动:实现对象+Thread代理+start * @author 16114 * */ public class StartThread implements Runnable{ /** * 线程入口点 */ public void run() { for(int i=0; i<5; i++) { System.out.println("一边听歌"); } } public static void main(String[] args) { //创建子类对象 //StartThread s = new StartThread(); //启动 //Thread st = new Thread(s); //st.start();//不保证立刻运行 cpu调用 //st.run();//普通方法的调用 //匿名:类只使用一次 new Thread(new StartThread()).start();; for(int i=0; i<5; i++) { System.out.println("一边Coding"); } } }
使用线程模拟龟兔赛跑
package com.zrl.thread; /** * 模拟龟兔赛跑 * @author 16114 * */ public class Racer implements Runnable{ private static String winner; //胜利者 @Override public void run() { for(int step=1;step<=100;step++) { //模拟兔子休息 if(step%10==0 && Thread.currentThread().getName().equals("rabbit")) {{ try { Thread.sleep(100); } catch (InterruptedException e) { e.printStackTrace(); } } } System.out.println(Thread.currentThread().getName()+"-->"+step); boolean flag = gameOver(step); if(flag) { break; } } } private boolean gameOver(int step) { if(winner != null) { //没有胜利者 return true; } else { if(step == 100) { winner = Thread.currentThread().getName(); System.out.println("winner ==> " + winner); return true; } } return false; } public static void main(String[] args) { Racer r = new Racer(); new Thread(r,"tortoise").start(); new Thread(r,"rabbit").start(); } }
静态代理类
package com.zrl.thread; public class StaticProxy { public static void main(String[] args) { new WeddingCompany(new You()).happyMarry(); //new Thread(线程对象).start(); } } interface Marry{ void happyMarry(); } class You implements Marry{ @Override public void happyMarry() { System.out.println("you and 嫦娥终于奔月..."); } } //代理角色 class WeddingCompany implements Marry{ //真实角色 private Marry target; public WeddingCompany(Marry target) { this.target = target; } @Override public void happyMarry() { ready(); this.target.happyMarry(); after(); } private void ready() { System.out.println("布置猪窝..."); } private void after() { System.out.println("闹玉兔..."); } }
lambda(jdk8新特性)
外部类——>静态内部类 ——>匿名内部类 ——>方法内部类
线程状态
看成足球比赛,每个线程当成球员。
新生状态 :入选23人大名单
就绪状态 :安排入场
运行状态:带球奔跑
阻塞状态:受到对方干扰(不是马上奔跑,从奔跑切换到就绪状态)
死亡状态:替换下场
如何切换到就绪状态
1.start()
2.解除阻塞状态
3.yield
4.jvm本身将CPU本地线程切换到其他线程
运行状态一定被CPU调度到了,不会从阻塞状态转到运行状态
如何切换到阻塞状态
1.sleep()延时,抱着资源不给别人
2.wait,红绿灯
3.join,插队
4.IO操作,read、write