Java简单实现多线程——继承thread类,Runnable类 callable类
简单模拟多线程,异步调用
package com.cl.demo01; //创建线程方式一;继承Thread类,重写run()方法,调用start开启线程 public class TestThread1 extends Thread{ @Override public void run() { //run方法线程体 for (int i = 0; i <100; i++) { System.out.println("run方法--"+i); } } public static void main(String[] args) { //main线程,主线程 TestThread1 thread1 = new TestThread1(); thread1.start(); for (int i = 0; i <100; i++) { System.out.println("多线程--"+i); } } } /* 总结:注意,线程开启不一定立即执行,由cpu调度执行 * */
练习Thread,实现多线程同步下载图片
注意,在实现前,需去官网下载“commons io.jar”这个jar包,因为要利用里面的工具去实现; package com.cl.demo01; import org.apache.commons.io.FileUtils; import java.io.File; import java.io.IOException; import java.net.URL; public class TestThread2 extends Thread { private String url;//网络图片地址 private String name;//保存的文件名 public TestThread2(String url,String name){ this.url=url; this.name=name; } @Override public void run() { WebDownloader webDownloader = new WebDownloader(); webDownloader.downloader(url,name); System.out.println("下载文件名:"+name); } public static void main(String[] args) { TestThread2 t1 = new TestThread2("https://pic.cnblogs.com/avatar/2053539/20200904094641.png","th1"); TestThread2 t2 = new TestThread2("https://pic.cnblogs.com/face/1959021/20200303171942.png","th2"); TestThread2 t3 = new TestThread2("https://pic.cnblogs.com/face/2124548/20200820122225.png","th3"); t1.start(); t2.start(); t3.start(); } } //下载器 class WebDownloader{ //下载方法 public void downloader(String url,String name){ try { FileUtils.copyURLToFile(new URL(url),new File(name)); } catch (IOException e) { e.printStackTrace(); System.out.println("IO 异常,downloader方法出现问题"); } } }
//不推荐使用,oop局限性
成功截图:注,为什么不是安123顺序下载的?
答,因为这个是模拟的多线程方法实现的
继承Runnablpackage com.cl.demo01;
//创建线程方式2:实现runnable接口实现类,调用Strat方法 public class TestThread3 implements Runnable{ @Override public void run() { //run方法线程体 for (int i = 0; i <100; i++) { System.out.println("run方法--"+i); } } public static void main(String[] args) { //创建runnable接口实现类对象 TestThread3 thread3 = new TestThread3(); //创建线程对象,通过线程对象来开启线程,代理 Thread thread = new Thread(thread3 ); thread.start(); // new Thread(thread3).start();上面两行代码的简化 for (int i = 0; i <100; i++) { System.out.println("多线程--"+i); } } } /* 跟继承Thread类相差不大,区别在于Runnable只有一个run方法,因此在最后调用start时要new thread好才可使用
推荐使用runnable ;方便同一个对象给多个线程使用 */
//练习:多个线程同时操作同一个对象
//模拟抢火车票
package com.cl.demo01; //思考:多个线程操作同一个资源的情况下,线程不安全,数据紊乱 public class TestThread4 implements Runnable{ //票数 private int tickNums=10; @Override public void run() { while (true){ if (tickNums<=0){ break; } System.out.println(Thread.currentThread().getName()+"拿到了第"+tickNums--+"票"); } } public static void main(String[] args) { TestThread4 ticket = new TestThread4(); new Thread(ticket,"king").start(); new Thread(ticket,"king2").start(); new Thread(ticket,"king3").start(); } }
//练习:模拟龟兔赛跑
package com.cl.demo01; //模拟龟兔赛跑 public class Race implements Runnable{ //胜利者 private static String winner; @Override public void run() { for (int i = 0; i < 100; i++) { //判断比赛是否结束 boolean flag=gameOver(i); //如果比赛结束了,就停止 if (flag){ break; } System.out.println(Thread.currentThread().getName()+"-->跑了"+i+"步"); } } //判断是否完成比赛 private boolean gameOver(int steps) { //判断是否有胜利者 if (winner != null) {//胜利者已经存在 return true; }{ if (steps>= 99) { winner = Thread.currentThread().getName(); System.out.println("winner is" + winner); return true; } } return false; } public static void main(String[] args) { Race race = new Race(); new Thread(race,"兔子").start(); new Thread(race,"乌龟").start(); } }