多线程
简介
创建线程
Thread class
- 继承Thread类(重点)
1.自定义线程类继承Thread类
2.重写run()方法,编写线程执行体
3.创建线程对象,调用start()方法启动线程
package edu.wzw.Thread;
//创建线程方法:继承Thread类,重写run()方法,调用start开启线程
//总结:注意,线程开启不一定立即执行,由cpu调度执行
public class demo01 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线程,主线程
//创建一个线程对象
demo01 demo01 = new demo01();
//使用start()方法开启线程
demo01.start();
for (int i = 0; i < 20; i++) {
System.out.println("你真是个大聪明"+i);
}
}
}
举例:下载网上图片
这里使用Maven,不使用Maven的话去导入io的包
<!-- https://mvnrepository.com/artifact/commons-io/commons-io -->
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.9.0</version>
</dependency>
主函数
package deu.wzw;
import org.apache.commons.io.FileUtils;
import java.io.File;
import java.io.IOException;
import java.net.URL;
//练习Thrad,实现多线程下载图片
public class Threads extends Thread {
private String url;//网络图片地址
private String name;//保存的文件名
public Threads(String url, String name) {
this.url = url;
this.name = name;
}
//下载图片线程的执行体
public void run() {
WebDownLoader webDownLoader = new WebDownLoader();
webDownLoader.downloder(url, name);
System.out.println("文件名" + name);
}
public static void main(String[] args) {
Threads t1 = new Threads("https://ss0.baidu.com/-Po3dSag_xI4khGko9WTAnF6hhy/zhidao/wh%3D450%2C600/sign=f491e04833fae6cd0ce1a3653a832312/bd315c6034a85edfee0bff5c4f540923dc5475cd.jpg", "1.jpg");
t1.start();
}
}
//下载器
class WebDownLoader{
//下载方法
public void downloder(String url,String name){
try {
FileUtils.copyURLToFile(new URL(url),new File(name));
} catch (IOException e) {
e.printStackTrace();
System.out.println("IO异常,downloder方法出现异常");
}
}
}
unnable接口
- 实现Runnable接口(核心重点)
1.定义MyRunnable实现Runnanle接口
2.实现Run()方法,编写线程执行体
3.创建线程对象,调用start()方法启动线程
package edu.wzw.Thread;
public class ThreadsRunnable implements Runnable {
@Override
public void run (){//run()方法线程
for (int i = 0; i < 20; i++) {
System.out.println("我是你妈"+i);
}
}
public static void main(String[] args) {
ThreadsRunnable threadsRunnable = new ThreadsRunnable();
// Thread thread = new Thread(threadsRunnable);
// thread.start(); 可以简写,如下
new Thread(threadsRunnable).start();
for (int i = 0; i < 20; i++) {
System.out.println("我是你爹"+i);
}
}
}
Callable接口
- 实现Callable接口
- 实现Callable接口,需要返回值类型
- 重写call方法,需要抛出异常
- 创建目标对象
- 创建执行服务:ExecutorService ser = Executors.newFixedThreadPool(1);
- 提交执行:Futureresult1 = ser.submit()
- 获取结果:boolean r1 = result.get();
- 关闭服务:ser.shoutdownNow();
小结
- 继承Thread类
- 子类继承Thread类具备多线程能力
- 启动线程:子类对象.start()
- 不建议使用:避免OOP单继承局限性
- 实现Runnable接口
- 实现接口Runnable具有的多线程能力
- 启动线程:传入目标对象+Thread对象.start()
- 推荐使用:避免单继承局限性,灵活方便,方便同一个对象被多个线程使用
package edu.wzw.Thread;
//多线程同时操作一个对象
//买动车票的例子
//发现问题:多个线程操作同一个资源的情况下,线程不安全,数据紊乱。线程同步解决
public class Threaddemo02 implements Runnable{
private int stickNum=10;//票数
@Override
public void run(){
while(true){
if (stickNum<=0){
break;
}//Thread.currentThread().getName()拿到线程的名字
System.out.println(Thread.currentThread().getName()+"拿到了"+stickNum--+"票");
}
}
public static void main(String[] args) {
Threaddemo02 stick = new Threaddemo02();
new Thread(stick,"wzw").start();
new Thread(stick,"死黄牛").start();
}
}