实现多线程的三种方法
①继承Thread类
例一:
源代码:
package cn.ecut.thread;
//创建线程方法一:继承Thread类,重写run方法,调用start方法开启线程
public class TestThread1 extends Thread {
//run方法-线程体
@Override
public void run() {
for (int i = 0; i <10 ; i++) {
System.out.println("run方法线程体"+i);
}
}
//main方法-主线程
public static void main(String[] args) {
//创建线程对象
TestThread1 testThread1=new TestThread1();
//调用start方法开启线程
testThread1.start();
for (int i = 0; i <10 ; i++) {
System.out.println("main方法线程体"+i);
}
}
}
运行结果:
例二:
源代码:
下载类:
package cn.ecut.thread;
import org.apache.commons.io.FileUtils;
import java.io.File;
import java.io.IOException;
import java.net.URL;
//下载类
public class WebDownloader {
//下载方法
public void downloader(String url,String fileName){
try {
FileUtils.copyURLToFile(new URL(url),new File(fileName));
} catch (IOException e) {
e.printStackTrace();
System.out.println("IO异常,downloader方法出现问题");
}
}
}
线程类:
package cn.ecut.thread;
//线程类
public class WebDownloaderThread extends Thread{
private String url;//需要下载的资源地址
private String fileName;//下载到哪里
public WebDownloaderThread(String url,String fileName){
this.url=url;
this.fileName=fileName;
}
@Override
public void run() {
WebDownloader webDownloader=new WebDownloader();
webDownloader.downloader(url,fileName);
System.out.println("下载的文件名为:"+fileName);
}
}
测试类:
package cn.ecut.thread;
public class TestWebDownloaderThread {
public static void main(String[] args) {
WebDownloaderThread t1=new WebDownloaderThread("https://ss0.baidu.com/7Po3dSag_xI4khGko9WTAnF6hhy/zhidao/pic/item/9c16fdfaaf51f3de9ba8ee1194eef01f3a2979a8.jpg","1.jpg");
WebDownloaderThread t2=new WebDownloaderThread("https://ss0.bdstatic.com/70cFuHSh_Q1YnxGkpoWK1HF6hhy/it/u=1546500353,2204894501&fm=26&gp=0.jpg","2.jpg");
WebDownloaderThread t3=new WebDownloaderThread("https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fi2.w.yun.hjfile.cn%2Fdoc%2F201303%2Fd5547c74-d9ad-4625-bd93-41c2817f1dff_03.jpg&refer=http%3A%2F%2Fi2.w.yun.hjfile.cn&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=jpeg?sec=1618666673&t=d4ea0b09d2b7545436244ca9fc6a3093","3.jpg");
t1.start();
t2.start();
t3.start();
}
}
运行结果:
②实现Runnable接口
例一:
源代码:
package cn.ecut.thread;
//创建线程方式二:实现Runnable接口,重写run方法,执行线程需要丢入runnable接口实现类,调用start方法
public class TestThread2 implements Runnable{
@Override
public void run() {
for (int i = 0; i <10 ; i++) {
System.out.println("run方法线程体"+i);
}
}
public static void main(String[] args) {
//创建runnable接口的实现类对象
TestThread2 testThread2=new TestThread2();
//创建线程对象,通过线程对象来开启我们的线程 “代理”
Thread thread=new Thread(testThread2);
thread.start();
//也可以用new Thread(thread).start();来代替上面两句
for (int i = 0; i <10 ; i++) {
System.out.println("main方法线程体"+i);
}
}
}
运行结果:
例二:
源代码:
package cn.ecut.thread;
//多个线程同时操作同一个资源的情况下,线程不安全,数据紊乱。
public class TicketThread implements Runnable{
//票数
private int ticketNums=10;
@Override
public void run() {
while(true){
if(ticketNums<=0){
break;
}
System.out.println(Thread.currentThread().getName()+"-->买到了第"+ticketNums--+"张票");
}
}
public static void main(String[] args) {
TicketThread ticketThread=new TicketThread();
new Thread(ticketThread,"小明").start();
new Thread(ticketThread,"小红").start();
new Thread(ticketThread,"小刚").start();
}
}
运行结果:
③实现Callable接口(略)
④模拟龟兔赛跑
源代码:
package cn.ecut.thread;
//模拟龟兔赛跑
public class Race implements Runnable{
//定义胜利者
private static String winner;
@Override
public void run() {
//模拟兔子休息
if(Thread.currentThread().getName().equals("兔子")){
try {
Thread.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
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>=100){
winner=Thread.currentThread().getName();
System.out.println("winner is "+winner);
}
return false;
}
public static void main(String[] args) {
Race race=new Race();
new Thread(race,"乌龟").start();
new Thread(race,"兔子").start();
}
}
运行结果: