线程简介
普通方法调用和多线程
线程实现(重点)
线程的创建
1.继承Thread类(重点)
第一步:自定义线程类继承Thread类。
第二步:重写run()方法,编写线程执行体。
第三步:创建线程对象,调用start()方法启动线程。
package com.tjrac.demo01;
//第一步:自定义线程类继承Thread类。
//第二步:重写run()方法,编写线程执行体。
//第三步:创建线程对象,调用start()方法启动线程。方法启动线程
public class TestThread1 extends Thread{
@Override
public void run() {
for(int i=0;i<20;i++){
System.out.println("我在看代码");
}
}
public static void main(String[] args) {
//创建线程对象
TestThread1 testThread1=new TestThread1();
//调用对象的start方法
testThread1.start();
for(int i=0;i<200;i++){
System.out.println("我学习多线程"+i);
}
}
}
实战下载图片
package com.tjrac.demo01;
import org.apache.commons.io.FileUtils;
import java.io.File;
import java.io.IOException;
import java.net.URL;
//第一步:自定义线程类继承Thread类。
//第二步:重写run()方法,编写线程执行体。
//第三步:创建线程对象,调用start()方法启动线程。方法启动线程
public class TestThread1 extends Thread{
private String url;//网络图片的地址
private String name;//保存的文件名
public TestThread1(String url,String name){
this.url=url;
this.name=name;
}
//下载线程的执行体
@Override
public void run() {
WedDownlaoder wedDownlaoder= new WedDownlaoder();
wedDownlaoder.Downlaoder(url,name);
System.out.println(name+"下载完成");
}
public static void main(String[] args) {
//创建线程对象
TestThread1 t1=new TestThread1("https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1577168219347&di=5bb4508ef618b0da3aed3d042eb8997e&imgtype=0&src=http%3A%2F%2Fimaegs.creditsailing.com%2Farticle%2F121%2F57_ua3ao__.jpg","陈声铭用多线程下载的图片01.jpg");
TestThread1 t2=new TestThread1("https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1577168219347&di=5bb4508ef618b0da3aed3d042eb8997e&imgtype=0&src=http%3A%2F%2Fimaegs.creditsailing.com%2Farticle%2F121%2F57_ua3ao__.jpg","陈声铭用多线程下载的图片02.jpg");
TestThread1 t3=new TestThread1("https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1577168219347&di=5bb4508ef618b0da3aed3d042eb8997e&imgtype=0&src=http%3A%2F%2Fimaegs.creditsailing.com%2Farticle%2F121%2F57_ua3ao__.jpg","陈声铭用多线程下载的图片03.jpg");
//调用对象的start方法
t1.start();
t2.start();
t3.start();
}
}
//下载器
class WedDownlaoder{
//下载方法
public void Downlaoder(String url,String name){
try {
FileUtils.copyURLToFile(new URL(url),new File(name));
} catch (IOException e) {
e.printStackTrace();
System.out.println("Downlaoder方法异常");
}
}
}
总结:线程开启不一定执行,由CPU调度执行,不推荐用Thread类,因为要不免单继承的局限性。
2.实现Runnable接口(重点)
第一步:实现Runnable接口。
第二步:重写run()方法。
第三步:将线程执行的接口放入接口实现类。
package com.tjrac.demo01;
//第一步:实现Runnable接口。
//第二步:重写run()方法。
//第三步:将线程执行的接口放入接口实现类。
public class TestRunnable01 implements Runnable{
@Override
public void run() {
for(int i=0;i<20;i++){
System.out.println("下载完成");
}
}
public static void main(String[] args) {
//创建Runnable接口的实现类对象
TestRunnable01 testRunnable = new TestRunnable01();
//创建线程对象,通过线程对象来启动线程
new Thread(testRunnable).start();
for(int i=0;i<500;i++){
System.out.println("下载完成"+i);
}
}
}
实战下载图片(荣耀战魂)
package com.tjrac.demo01;
import org.apache.commons.io.FileUtils;
import java.io.File;
import java.io.IOException;
import java.net.URL;
public class TestRunnable02 implements Runnable{
private String url;//网络图片的地址
private String name;//保存的文件名
public TestRunnable02(String url,String name){
this.url=url;
this.name=name;
}
//下载线程的执行体
@Override
public void run() {
RunnableDownlaoder runnableDownlaoder= new RunnableDownlaoder();
runnableDownlaoder.Downlaoder(url,name);
System.out.println(name+"下载完成");
}
public static void main(String[] args) {
//创建线程对象
TestRunnable02 t1=new TestRunnable02("https://imgsa.baidu.com/forum/pic/item/8a13632762d0f703b83556ae07fa513d2697c539.jpg","陈声铭用多线程下载的图片04.jpg");
//调用对象的start方法
new Thread(t1).start();
}
}
//下载器
class RunnableDownlaoder{
//下载方法
public void Downlaoder(String url,String name){
try {
FileUtils.copyURLToFile(new URL(url),new File(name));
} catch (IOException e) {
e.printStackTrace();
System.out.println("Downlaoder方法异常");
}
}
}
总结:推挤使用Runnable接口,方便灵活,可以一个对象被多个线程使用,但是会出现多线程并发的问题。
多个线程同时操作一个对象实战
卖火车票
package com.tjrac.demo01;
//多个线程同时操作一个对象
//卖火车票
public class TestRunnable03 implements Runnable {
private int ticket=10;
@Override
public void run() {
//模拟延时
try {
Thread.sleep(200);
} catch (InterruptedException e) {
e.printStackTrace();
}
while (true) {
if(ticket<=0){
break;
}
System.out.println(Thread.currentThread().getName()+"买到了第"+ticket--+"票");
}
}
public static void main(String[] args) {
TestRunnable03 testRunnable03=new TestRunnable03();
new Thread(testRunnable03,"陈声铭").start();
new Thread(testRunnable03,"雷志明").start();
new Thread(testRunnable03,"唐可明").start();
new Thread(testRunnable03,"陈笑").start();
}
}
3.实现Callable接口
实战下载图片
package com.tjrac.demo01;
import org.apache.commons.io.FileUtils;
import java.io.File;
import java.io.IOException;
import java.net.URL;
import java.util.concurrent.*;
public class TestCallable01 implements Callable<Boolean> {
private String url;//网络图片的地址
private String name;//保存的文件名
public TestCallable01(String url,String name){
this.url=url;
this.name=name;
}
//下载线程的执行体
@Override
public Boolean call() {
RunnableDownlaoder runnableDownlaoder= new RunnableDownlaoder();
runnableDownlaoder.Downlaoder(url,name);
System.out.println(name+"下载完成");
return true;
}
public static void main(String[] args) throws ExecutionException, InterruptedException {
//创建线程对象
TestCallable01 t1=new TestCallable01("https://imgsa.baidu.com/forum/w%3D580%3B/sign=16a0044f35f33a879e6d0012f6671138/37d12f2eb9389b508c5b672d8a35e5dde7116e2d.jpg","陈声铭用多线程下载的图片05.jpg");
//创建执行服务
ExecutorService ser = Executors.newFixedThreadPool(1);
//提交执行
Future<Boolean> r1=ser.submit(t1);
//获取结果
boolean rs1=r1.get();
//关闭服务器
ser.shutdownNow();
}
}
//下载器
class CallableDownlaoder{
//下载方法
public void Downlaoder(String url,String name){
try {
FileUtils.copyURLToFile(new URL(url),new File(name));
} catch (IOException e) {
e.printStackTrace();
System.out.println("Downlaoder方法异常");
}
}
}