在程序中main()为主线程,是系统的入口,用于执行整个程序。在普通方法调用中只有主线程一条执行路径;多线程则是有主线程和子线程多条执行路径。
一.继承Thread类
自定义线程类继承Thread类重写run()方法,编写线程执行体创建线程对象,调用start()方法启动线程 //创建方式一:继承Thread类,重写run()方法,调用start开启线程 public class testThread1 extends Thread{ @Override public void run() { //run方法线程体 for(int i = 0; i < 20; i++) { System.out.println("子线程"+i); } } public static void main(String[] args) { //main主线程 // 创建一个线程对象 testThread1 thread1 = new testThread1(); //调用start()方法开启线程 thread1.start(); for(int i = 0; i < 20; i++) { System.out.println("主线程"+i); } } }二.实现Runnable()接口
定义线程类实现Runnable接口实现run()方法,编写线程执行体创建线程对象,调用start()方法启动线程 利用接口实现多线程可以避免单继承的局限性,方便一个对象被多个线程使用。 //创建线程方式2:实现runnable接口,重写run方法,执行线程需要丢入runnable接口实现类,调用start方法 public class testThread3 implements Runnable { @Override public void run() { //run方法线程体 for(int i = 0; i < 20; i++) { System.out.println("子线程"+i); } } public static void main(String[] args) { //main主线程 // 创建runnable接口的实现类对象 testThread3 thread3 = new testThread3(); //创建线程对象,通过线程对象来开启我们的线程,代理 Thread thread = new Thread(thread3); thread.start(); for(int i = 0; i < 20; i++) { System.out.println("主线程"+i); } } }三.实现Callable接口
实现Callable接口,需要返回值重写call方法,需要抛出异常创建目标对象创建执行服务:ExecutorService ser = Executors.NewFixedThreadPool(1);提交执行:Future result = ser.submit(t1);获取结果:boolean r1 = result.get();关闭服务:ser.shutdownNow();第三个方式我们用一个例子来实现。这个例子是网图下载,我们需要用到一个别人写好的jar包,common-io包,到百度自行下载即可。在项目中导入jar包。首先我们先写个下载类:
//下载器 class WebDownloader{ //下载方法 public void downloader(String url,String name) { try { FileUtils.copyURLToFile(new URL(url),new File(name)); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); System.out.println("io异常,dawnloader()方法错误"); } } }接着写我们的主类
//创建方式三:实现Callable接口 public class ThreadCallable implements Callable<Boolean> { private String url;//网络图片地址 private String name;//保存文件名 public ThreadCallable(String url,String name) { this.url = url; this.name = name; } @Override public Boolean call() { WebDownloader webDownloader = new WebDownloader(); webDownloader.downloader(url, name); System.out.println("下载文件名为:"+name); return true; } public static void main(String[] args) throws InterruptedException, ExecutionException { ThreadCallable t1 = new ThreadCallable("https://image.baidu.com/search/detail?ct=503316480&z=0&ipn=false&word=电脑壁纸&step_word=&hs=0&pn=0&spn=0&di=17930&pi=0&rn=1&tn=baiduimagedetail&is=0,0&istype=0&ie=utf-8&oe=utf-8&in=&cl=2&lm=-1&st=undefined&cs=1705581946,4177791147&os=3092380308,906356246&simid=4087421280,717844758&adpicid=0&lpn=0&ln=30&fr=&fmq=1601886433058_R&fm=&ic=undefined&s=undefined&hd=undefined&latest=undefined©right=undefined&se=&sme=&tab=0&width=undefined&height=undefined&face=undefined&ist=&jit=&cg=wallpaper&bdtype=0&oriquery=电脑壁纸&objurl=http://attachments.gfan.com/forum/201503/19/211608ztcq7higicydxhsy.jpg&fromurl=ippr_z2C$qAzdH3FAzdH3Fkkf_z&e3B2uwg_z&e3Bv54AzdH3Fwg165t1-0bb0c0c-swfp-8_z&e3Bip4s&gsm=1&rpstart=0&rpnum=0&islist=&querylist=&force=undefined","1.jpg"); ThreadCallable t2 = new ThreadCallable("https://image.baidu.com/search/detail?ct=503316480&z=0&ipn=false&word=电脑壁纸&step_word=&hs=0&pn=1&spn=0&di=144650&pi=0&rn=1&tn=baiduimagedetail&is=0,0&istype=0&ie=utf-8&oe=utf-8&in=&cl=2&lm=-1&st=undefined&cs=1262773730,4108667670&os=4089191533,296881675&simid=4196037961,729463796&adpicid=0&lpn=0&ln=30&fr=&fmq=1601886433058_R&fm=&ic=undefined&s=undefined&hd=undefined&latest=undefined©right=undefined&se=&sme=&tab=0&width=undefined&height=undefined&face=undefined&ist=&jit=&cg=wallpaper&bdtype=0&oriquery=电脑壁纸&objurl=http://b-ssl.duitang.com/uploads/item/201603/04/20160304163044_Ze4ad.jpeg&fromurl=ippr_z2C$qAzdH3FAzdH3Fooo_z&e3B17tpwg2_z&e3Bv54AzdH3Fks52AzdH3F?t1=c9da8d098&gsm=1&rpstart=0&rpnum=0&islist=&querylist=&force=undefined","2.jpg"); ThreadCallable t3 = new ThreadCallable("https://image.baidu.com/search/detail?ct=503316480&z=0&ipn=false&word=电脑壁纸&step_word=&hs=0&pn=2&spn=0&di=156200&pi=0&rn=1&tn=baiduimagedetail&is=0,0&istype=0&ie=utf-8&oe=utf-8&in=&cl=2&lm=-1&st=undefined&cs=3883283873,2209997708&os=542829189,2419561689&simid=0,0&adpicid=0&lpn=0&ln=30&fr=&fmq=1601886433058_R&fm=&ic=undefined&s=undefined&hd=undefined&latest=undefined©right=undefined&se=&sme=&tab=0&width=undefined&height=undefined&face=undefined&ist=&jit=&cg=wallpaper&bdtype=0&oriquery=电脑壁纸&objurl=http://a4.att.hudong.com/05/50/300001069758129557502950786.jpg&fromurl=ippr_z2C$qAzdH3FAzdH3Fooo_z&e3Bzi5g2rjg2y7_z&e3BvgAzdH3FpAzdH3Faaaabcbm8AzdH3F&gsm=1&rpstart=0&rpnum=0&islist=&querylist=&force=undefined","3.jpg"); //创建执行服务 ExecutorService ser = Executors.newFixedThreadPool(3); //提交执行 Future<Boolean> r1 = ser.submit(t1); Future<Boolean> r2 = ser.submit(t2); Future<Boolean> r3 = ser.submit(t3); //获取结果 boolean rs1 = r1.get(); boolean rs2 = r2.get(); boolean rs3 = r3.get(); //关闭服务 ser.shutdownNow(); } }以上就是java实现多线程的三种方法。下面附加两个多线程的例子
//多个线程同时操作同一个对象 //买火车票的例子 //问题:多个线程同时操作一个资源的情况下,线程不安全,数据紊乱 public class testThread4 implements Runnable { //票数 private int ticketNums = 10; @Override public void run() { // TODO Auto-generated method stub while(true) { if(ticketNums<=1) { break; } //模拟延时 try { Thread.sleep(200); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } System.out.println(Thread.currentThread().getName()+"-->拿到了第"+ticketNums--+"票"); } } public static void main(String[] args) { testThread4 ticket = new testThread4(); new Thread(ticket,"小明").start(); new Thread(ticket,"老师").start(); new Thread(ticket,"黄牛").start(); } } //模拟龟兔赛跑 public class Race implements Runnable { //胜利者 private static String winner; @Override public void run() { // TODO Auto-generated method stub for(int i = 0; i <= 100; i++) { //模拟兔子休息 if(Thread.currentThread().getName().equals("兔子")&& i%10 == 0) { try { Thread.sleep(20); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } //判断比赛是否结束 boolean flag = gameOver(i); //如果结束,终结程序 if(flag) { break; } System.out.println(Thread.currentThread().getName()+"-->跑了"+i+"步"); } } //判断是否完成比赛 private boolean gameOver(int steps) { //判断是否有胜利者 if(winner != null) { //已经有胜利者 return true; }else if(steps == 100){ 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(); } }