继承Thread
package com.bin.thread;
public class ThreadTest01 extends Thread {
@Override
public void run() {
for (int i = 0; i <100; i++){
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("我在执行run方法--"+i);
}
}
public static void main(String[] args) throws InterruptedException {
ThreadTest01 test01 = new ThreadTest01();
test01.start();
for (int i = 0; i <100; i++){
Thread.sleep(100);
System.out.println("我在执行main方法--"+i);
}
}
}
代码执行效果:
子类继承Thread类具备多线程能力
启动线程:子类对象.strat();
不建议使用:避免面向对象单继承的局限性。
实现Runable
package com.bin.thread;
/**
*
*/
public class ThreadTest03 implements Runnable {
public void run() {
for (int i = 0; i <100; i++){
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("我在执行run方法--"+i);
}
}
public static void main(String[] args) throws InterruptedException {
ThreadTest03 threadTest03 = new ThreadTest03();
new Thread(threadTest03).start();
for (int i = 0; i <100; i++){
Thread.sleep(100);
System.out.println("我在执行main方法--"+i);
}
}
}
执行效果:
通过实现Runable接口具备多线程能力
启动线程:new Thread(实现类实例).start();
推荐使用:避免单继承的局限性,灵活方便,方便同一对象被多个线程使用。
小练习:启动多线程下载图片
导入jar包
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.6</version>
</dependency>
实现功能:
package com.bin.thread;
import org.apache.commons.io.FileUtils;
import java.io.File;
import java.io.IOException;
import java.net.URL;
public class ThreadTest02 extends Thread {
private String url;
private String name;
public ThreadTest02(String url, String name) {
this.url = url;
this.name = name;
}
@Override
public void run() {
WebDownload download = new WebDownload();
download.downloadPicture(url,name);
System.out.println("下载了"+name+"图片");
}
public static void main(String[] args) {
ThreadTest02 threadTest1 = new ThreadTest02("https://picsum.photos/536/354", "1.jpg");
ThreadTest02 threadTest2 = new ThreadTest02("https://picsum.photos/seed/picsum/536/354", "2.jpg");
ThreadTest02 threadTest3 = new ThreadTest02("https://picsum.photos/id/1084/536/354?grayscale", "3.jpg");
threadTest1.start();
threadTest2.start();
threadTest3.start();
}
}
class WebDownload {
public void downloadPicture(String url ,String name){
try {
FileUtils.copyURLToFile(new URL(url),new File(name));
} catch (IOException e) {
e.printStackTrace();
}
}
}
执行效果:
通过控制台的输出结果,可以观察到图片下载并不是顺序执行的,而是cpu通过线程调度执行。
通过实现Callable接口实现图片下载
package com.bin.callable;
import com.bin.thread.ThreadTest02;
import com.bin.thread.WebDownload;
import java.util.concurrent.*;
public class CallableTest01 implements Callable<Boolean> {
private String url;
private String name;
public CallableTest01(String url,String name) {
this.url = url;
this.name = name;
}
public Boolean call() throws Exception {
WebDownload download = new WebDownload();
download.downloadPicture(url,name);
System.out.println("下载了图片"+name);
return true;
}
public static void main(String[] args) {
CallableTest01 c1 = new CallableTest01("https://picsum.photos/536/354", "1.jpg");
CallableTest01 c2 = new CallableTest01("https://picsum.photos/seed/picsum/536/354", "2.jpg");
CallableTest01 c3 = new CallableTest01("https://picsum.photos/id/1084/536/354?grayscale", "3.jpg");
//创建线程池
ExecutorService executorService = Executors.newFixedThreadPool(3);
//提交执行
Future<Boolean> submit1 = executorService.submit(c1);
Future<Boolean> submit2 = executorService.submit(c2);
Future<Boolean> submit3 = executorService.submit(c3);
//获取结果
try {
Boolean b1 = submit1.get();
Boolean b2 = submit2.get();
Boolean b3 = submit3.get();
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
//关闭线程池
executorService.shutdownNow();
}
}
执行效果:
小测试
测试多个线程操作同一对象会不会出现线程安全问题。
package com.bin.thread;
public class ThreadTest04 implements Runnable {
private Integer ticketNums = 10;
public void run() {
while (true){
if (ticketNums<=0){
break;
}
System.out.println(Thread.currentThread().getName()+"抢到了第"+ticketNums+"张票");
ticketNums--;
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public static void main(String[] args) {
ThreadTest04 threadTest04 = new ThreadTest04();
//多个线程操作同一对象
new Thread(threadTest04,"腾讯主席").start();
new Thread(threadTest04,"阿里主席").start();
new Thread(threadTest04,"网易主席").start();
new Thread(threadTest04,"扫地的我").start();
}
}
执行结果:
结果很明显。
注:本次学习于狂神老师的b站视频。网址:https://www.bilibili.com/video/BV1V4411p7EF