实现多线程编程的方式主要有有两种,一种是继承 Thread 类,另一种是实现 Runnable 接口。使用继承 Thread 类创建线程,最大的局限就是不能多继承,所以为了支持多继承,完全可以实现 Runnable 接口的方式。需要说明的是,这两种方式在工作时的性质都是一样的,没有本质的区别。
1.继承Thread类,需要重写run方法,然后调用start()方法,三步走
import java.io.File;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import org.apache.commons.io.FileUtils;
public class Thread01 extends Thread {
private URL url;
private File name;
public void run() {
try {
webserver();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println(name+"is already");
}
public void webserver() throws IOException {
FileUtils.copyURLToFile(url, name);
}
public Thread01(URL url,File name) {
this.url=url;
this.name=name;
}
public static void main(String[] args) throws MalformedURLException {
//创建子类对象
Thread01 td1=new Thread01(new URL("https://image.baidu.com/search/detail?ct=503316480&z=0&ipn=d&word=%E5%9B%BE%E7%89%87&step_word=&hs=0&pn=1&spn=0&di=181720&pi=0&rn=1&tn=baiduimagedetail&is=0%2C0&istype=0&ie=utf-8&oe=utf-8&in=&cl=2&lm=-1&st=undefined&cs=3173584241%2C3533290860&os=1133571898%2C402444249&simid=3493630544%2C246115770&adpicid=0&lpn=0&ln=1410&fr=&fmq=1583203139520_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=&bdtype=0&oriquery=&objurl=http%3A%2F%2Fa0.att.hudong.com%2F78%2F52%2F01200000123847134434529793168.jpg&fromurl=ippr_z2C%24qAzdH3FAzdH3Fp7rtwg_z%26e3Bkwthj_z%26e3Bv54AzdH3Ftrw1AzdH3Fwa_0b_cd_a8daaaaa8dnb908n99n9cdl0ln8mb_3r2_z%26e3Bip4s&gsm=1&rpstart=0&rpnum=0&islist=&querylist=&force=undefined"),new File("tiger.png"));
Thread01 td2=new Thread01(new URL("https://image.baidu.com/search/detail?ct=503316480&z=0&ipn=d&word=%E5%9B%BE%E7%89%87&step_word=&hs=0&pn=3&spn=0&di=8030&pi=0&rn=1&tn=baiduimagedetail&is=0%2C0&istype=0&ie=utf-8&oe=utf-8&in=&cl=2&lm=-1&st=undefined&cs=1906469856%2C4113625838&os=1062705421%2C520912533&simid=3285371631%2C209838447&adpicid=0&lpn=0&ln=1410&fr=&fmq=1583203139520_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=&bdtype=0&oriquery=&objurl=http%3A%2F%2Fa2.att.hudong.com%2F36%2F48%2F19300001357258133412489354717.jpg&fromurl=ippr_z2C%24qAzdH3FAzdH3Fp7rtwg_z%26e3Bkwthj_z%26e3Bv54AzdH3Ftrw1AzdH3Fwd_nm_9b_8lnaaaa8nc0dcb8nn98d9blnc9080_3r2_z%26e3Bip4s&gsm=3&rpstart=0&rpnum=0&islist=&querylist=&force=undefined"), new File("strawberry.png"));
td1.start();
td2.start();
}
}
2.实现runnable 接口,重写run方法,使用start()方法调用,由于runnable接口中只有一个抽象方法run(),所以需要创建代理类Thread才能调用start()方法(方便共享资源,避免单继承的弊端)
package cn.xl.thread;
import java.io.File;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import org.apache.commons.io.FileUtils;
public class RunImplement implements Runnable {
public static void main(String[] args) throws MalformedURLException {
//创建实现类对象
RunImplement sr1=new RunImplement(new URL("https://image.baidu.com/search/detail?ct=503316480&z=0&ipn=d&word=%E5%9B%BE%E7%89%87&step_word=&hs=0&pn=1&spn=0&di=181720&pi=0&rn=1&tn=baiduimagedetail&is=0%2C0&istype=0&ie=utf-8&oe=utf-8&in=&cl=2&lm=-1&st=undefined&cs=3173584241%2C3533290860&os=1133571898%2C402444249&simid=3493630544%2C246115770&adpicid=0&lpn=0&ln=1410&fr=&fmq=1583203139520_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=&bdtype=0&oriquery=&objurl=http%3A%2F%2Fa0.att.hudong.com%2F78%2F52%2F01200000123847134434529793168.jpg&fromurl=ippr_z2C%24qAzdH3FAzdH3Fp7rtwg_z%26e3Bkwthj_z%26e3Bv54AzdH3Ftrw1AzdH3Fwa_0b_cd_a8daaaaa8dnb908n99n9cdl0ln8mb_3r2_z%26e3Bip4s&gsm=1&rpstart=0&rpnum=0&islist=&querylist=&force=undefined"),new File("tiger.png"));
RunImplement sr2=new RunImplement(new URL("https://image.baidu.com/search/detail?ct=503316480&z=0&ipn=d&word=%E5%9B%BE%E7%89%87&step_word=&hs=0&pn=3&spn=0&di=8030&pi=0&rn=1&tn=baiduimagedetail&is=0%2C0&istype=0&ie=utf-8&oe=utf-8&in=&cl=2&lm=-1&st=undefined&cs=1906469856%2C4113625838&os=1062705421%2C520912533&simid=3285371631%2C209838447&adpicid=0&lpn=0&ln=1410&fr=&fmq=1583203139520_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=&bdtype=0&oriquery=&objurl=http%3A%2F%2Fa2.att.hudong.com%2F36%2F48%2F19300001357258133412489354717.jpg&fromurl=ippr_z2C%24qAzdH3FAzdH3Fp7rtwg_z%26e3Bkwthj_z%26e3Bv54AzdH3Ftrw1AzdH3Fwd_nm_9b_8lnaaaa8nc0dcb8nn98d9blnc9080_3r2_z%26e3Bip4s&gsm=3&rpstart=0&rpnum=0&islist=&querylist=&force=undefined"), new File("strawberry.png"));
//创建代理类对象
Thread t1=new Thread(sr1);
Thread t2=new Thread(sr2);
t1.start();
t2.start();
}
private URL url;
private File name;
public void run() {
for(int i=0;i<1000;i++) {
System.out.println(name);
}
}
public void webserver() throws IOException {
FileUtils.copyURLToFile(url, name);
}
public RunImplement(URL url,File name) {
this.url=url;
this.name=name;
}
}
3.runnable共享资源,一个资源多个线程共享,其中Thread.currentThread()指的是当前线程的引用
public class Web12306 implements Runnable{
private int ticketNums=99;
@Override
public void run() {
while(true) {
if(ticketNums<0)
break;
System.out.println(Thread.currentThread().getName()+"-->"+ticketNums--);
}
}
public static void main(String[] args) {
Web12306 web=new Web12306();
new Thread(web, "码农").start();
new Thread(web, "码畜").start();
new Thread(web, "蚂蝗").start();
}
}
4.实现Callable(初学者了解),首先要实现callable接口,创建Callable方法,run()方法改为call()方法,并且可以返回异常
一、创建目标对象
二、创建执行服务
三、提交执行
四、获取结果
五、关闭服务
5.代理
静态代理由程序员创建或由特定工具自动生成源代码,再对其编译。在程序运行前,代理类的.class文件就已经存在了。动态代理类:在程序运行时,运用反射机制动态创建而成。