线程
程序是指令、数据的有序集合,是静态的概念
进程是执行程序的一次执行过程,是动态概念
一个进程中可包含多个线程,java中有两个默认线程:main线程 和 gc线程
线程是CPU调度和执行的单位
线程创建1:继承Thread类(不推荐,避免OOP单继承局限性)
创建线程:继承Thread类,重写run方法
public class TestThread1 extends Thread{
@Override
public void run() {
for (int i = 0; i < 1000; i++) {
System.out.println("线程1............");
}
}
}
运行线程:创建对象,调用start方法
public class Test01 {
public static void main(String[] args) {
TestThread1 thread1 = new TestThread1();
thread1.start();
for (int i = 0; i < 1000; i++) {
System.out.println("main线程..........");
}
}
}
示例:多线程下载网络图片
依赖包:
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.6</version>
</dependency>
public class TestThread2 extends Thread{
private String url;
private String name;
public TestThread2(String url, String name) {
this.url=url;
this.name=name;
}
@Override
public void run() {
WebDownloader webDownloader = new WebDownloader();
webDownloader.downloader(url, name);
System.out.println("下载完成"+ name);
}
public static void main(String[] args) {
String a = "https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1598452051882&di=2c0925ea23483ac6c49affd40cbfb419&imgtype=0&src=http%3A%2F%2Fx0.ifengimg.com%2Fucms%2F2019_42%2FB575B6769D2A535CCB8186FB971B65DF853D14A0_w1620_h810.jpg";
TestThread2 t1 = new TestThread2(a,"1.jpg");
TestThread2 t2 = new TestThread2(a,"2.jpg");
TestThread2 t3 = new TestThread2(a,"3.jpg");
t1.start();
t2.start();
t3.start();
}
}
class WebDownloader {
public void downloader(String url, String name) {
try {
FileUtils.copyURLToFile(new URL(url), new File(name));
} catch (IOException e) {
System.out.println("IO异常,downloader方法出现问题");
e.printStackTrace();
}
}
}
线程创建2:实现Runnable接口(推荐,避免单继承局限性,灵活,方便同一对象被多个线程使用)
创建线程:实现Runnable接口,实现run方法
开启线程:创建自定义的线程对象和Thread类对象,将自定义的线程对象传入Thread类构造,调用start方法
源码:Thread类实现了Runnable接口
public class TestThread3 implements Runnable{
@Override
public void run() {
for (int i = 0; i < 1000; i++) {
System.out.println("实现Runnable接口的线程......");
}
}
public static void main(String[] args) {
TestThread3 testThread3 = new TestThread3();
new Thread(testThread3).start();
for (int i = 0; i < 1000; i++) {
System.out.println("main线程.............");
}
}
}
示例修改:多线程下载网络图片
public class TestThread2 implements Runnable{
private String url;
private String name;
public TestThread2(String url, String name) {
this.url=url;
this.name=name;
}
@Override
public void run() {
WebDownloader webDownloader = new WebDownloader();
webDownloader.downloader(url, name);
System.out.println("下载完成"+ name);
}
public static void main(String[] args) {
String a = "https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1598452051882&di=2c0925ea23483ac6c49affd40cbfb419&imgtype=0&src=http%3A%2F%2Fx0.ifengimg.com%2Fucms%2F2019_42%2FB575B6769D2A535CCB8186FB971B65DF853D14A0_w1620_h810.jpg";
TestThread2 t1 = new TestThread2(a,"1.jpg");
TestThread2 t2 = new TestThread2(a,"2.jpg");
TestThread2 t3 = new TestThread2(a,"3.jpg");
new Thread(t1).start;
new Thread(t2).start;
new Thread(t3).start;
}
}
class WebDownloader {
public void downloader(String url, String name) {
try {
FileUtils.copyURLToFile(new URL(url), new File(name));
} catch (IOException e) {
System.out.println("IO异常,downloader方法出现问题");
e.printStackTrace();
}
}
}
多个线程同时操作同一个对象示例:抢票
问题:多个线程同时操作同一资源时,线程不安全,出现数据紊乱现象
public class TestThread4 implements Runnable{
private int ticketNums = 10;
@Override
public void run() {
while(true) {
if(ticketNums<=0) {
break;
}
try {
Thread.sleep(100);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
int num = 11-ticketNums;
System.out.println(Thread.currentThread().getName()+"拿到了第"+num+"张票");
ticketNums--;
}
}
public static void main(String[] args) {
TestThread4 testThread4 = new TestThread4();
new Thread(testThread4,"张三").start();
new Thread(testThread4,"李四").start();
new Thread(testThread4,"王五").start();
}
}
李四拿到了第1张票
王五拿到了第1张票
张三拿到了第1张票
张三拿到了第4张票
王五拿到了第4张票
李四拿到了第4张票
王五拿到了第7张票
张三拿到了第7张票
李四拿到了第7张票
张三拿到了第10张票
王五拿到了第10张票
李四拿到了第10张票
线程创建3:实现Callable接口(了解即可)
创建线程:实现Callable接口,实现call()方法
运行线程:创建线程池,提交执行线程对象,获取结果,关闭线程池
public class TestThread5 implements Callable<Boolean>{
private String url;
private String name;
public TestThread5(String url, String name) {
this.url=url;
this.name=name;
}
@Override
public Boolean call() throws Exception {
WebDownloader webDownloader = new WebDownloader();
webDownloader .downloader(url, name);
System.out.println("下载完成"+ name);
return true;
}
public static void main(String[] args) throws InterruptedException, ExecutionException {
String a = "https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1598452051882&di=2c0925ea23483ac6c49affd40cbfb419&imgtype=0&src=http%3A%2F%2Fx0.ifengimg.com%2Fucms%2F2019_42%2FB575B6769D2A535CCB8186FB971B65DF853D14A0_w1620_h810.jpg";
TestThread5 t1 = new TestThread5(a,"1.jpg");
TestThread5 t2 = new TestThread5(a,"2.jpg");
TestThread5 t3 = new TestThread5(a,"3.jpg");
//创建执行服务
ExecutorService threadPool = Executors.newFixedThreadPool(3);
//提交执行
Future<Boolean> result1 = threadPool.submit(t1);
Future<Boolean> result2 = threadPool.submit(t2);
Future<Boolean> result3 = threadPool.submit(t3);
//获取结果
Boolean r1 = result1.get();
Boolean r2 = result2.get();
Boolean r3 = result3.get();
System.out.println(r1);
System.out.println(r2);
System.out.println(r3);
//关闭服务
threadPool.shutdownNow();
}
}
class WebDownloader {
public void downloader(String url, String name) {
try {
FileUtils.copyURLToFile(new URL(url), new File(name));
} catch (IOException e) {
System.out.println("IO异常,downloader方法出现问题");
e.printStackTrace();
}
}
}
Lambda表达式
避免匿名内部类定义过多
让代码更简洁
函数式接口:只包含唯一一个抽象方法的接口叫函数式接口
public interface Runnable{
public abstract void run();
}
传统方式:
public class TestLambda {
public static void main(String[] args) {
ILike like = new Like();
like.lambda();
}
}
//定义一个函数式接口
interface ILike{
void lambda();
}
//实现类
class Like implements ILike{
@Override
public void lambda() {
System.out.println("I like lambda");
}
}
使用Lambda表达式:
public class TestLambda {
public static void main(String[] args) {
ILike like = ()->{
System.out.println("I like lambda2");
};
like.lambda();
}
}
//定义一个函数式接口
interface ILike{
void lambda();
}