多线程学习笔记01线程、进程、多线程与线程创建

@Override

public void run() {

WebDownLoader webDownLoader = new WebDownLoader();

webDownLoader.downLoader(url, name);

System.out.println(“下载了文件,名为:” + name);

}

public static void main(String[] args) {

TestThread2 t1 = new TestThread2(“https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fup.enterdesk.com%2F2021%2Fedpic_source%2F1d%2F31%2F79%2F1d3179f050039cc45f9f62a105b12c3a_8.jpg&refer=http%3A%2F%2Fup.enterdesk.com&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=jpeg?sec=1646039329&t=700647f4c668754644f743467bda0e09”, “1.jpg”);

TestThread2 t2 = new TestThread2(“https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fup.enterdesk.com%2F2021%2Fedpic_source%2F1d%2F31%2F79%2F1d3179f050039cc45f9f62a105b12c3a_8.jpg&refer=http%3A%2F%2Fup.enterdesk.com&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=jpeg?sec=1646039329&t=700647f4c668754644f743467bda0e09”, “2.jpg”);

TestThread2 t3 = new TestThread2(“https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fup.enterdesk.com%2F2021%2Fedpic_source%2F1d%2F31%2F79%2F1d3179f050039cc45f9f62a105b12c3a_8.jpg&refer=http%3A%2F%2Fup.enterdesk.com&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=jpeg?sec=1646039329&t=700647f4c668754644f743467bda0e09”, “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) {

e.printStackTrace();

System.out.println(“IO异常,downLoader方法出现问题”);//异常提醒

}

}

}

在这里插入图片描述

实现Runnable
  • 定义MyRunnable类实现Runnable接口

  • 实现run()方法,编写线程执行体

  • 创建线程对象,调用start()方法启动线程

//创建线程方式二:实现Runnable接口

public class TestThread3 implements Runnable{

@Override

public void run() {

//run方法线程体

for (int i = 0; i < 20; i++) {

System.out.println(“我在看代码—” + i);

}

}

public static void main(String[] args) {

//创建runnable接口的实现类对象

TestThread3 testThread3 = new TestThread3();

//创建线程对象,通过线程对象开启线程

// Thread thread = new Thread();

// thread.start();

new Thread(testThread3).start();

for (int i = 0; i < 20; i++) {

System.out.println(“我在学习多线程–” + i);

}

}

}

在这里插入图片描述

线程同时执行。

小结:

  • 继承Thread类:
子类继承Thread类具备多线程能力  
启动线程:子类对象.start()  
**不建议使用,,避免OOP单继承局限性**
  • 实现Runnable接口:
实现接口Runnable具有多线程能力  
启动线程:传入目标对象+Thread对象.start()  
**推荐使用,,避免单继承局限性,灵活方便,方便同一个对象被多个线程使用**
初识并发问题

典型案例:买火车票

//多个线程同时操作同一个对象

//买火车票

public class TestThread4 implements Runnable {

//票数

private int ticketNums = 10;

@Override

public void run() {

while (true) {

if (ticketNums <= 0) {

break;

}

//模拟延时

try {

Thread.sleep(200);

} catch (InterruptedException e) {

e.printStackTrace();

}

System.out.println(Thread.currentThread().getName() + “拿到了第” + ticketNums-- + “票”);

}

}

public static void main(String[] args) {

TestThread4 testThread4 = new TestThread4();

new Thread(testThread4, “小明”).start();

new Thread(testThread4, “小红”).start();

new Thread(testThread4, “黄牛”).start();

}

}

在这里插入图片描述

其中:

Thread.currentThread().getName():获得当前执行线程的名字

Thread.sleep(200);:模拟延时

但是通过观察运行情况,发现有不同人拿到同一张票的情况,即多个线程操作同一个资源,线程不安全。

案例:龟兔赛跑

//模拟龟兔赛跑

public class Race implements Runnable {

//胜利者

private static String winner;

@Override

public void run() {

for (int i = 0; i <= 100; i++) {

//模拟兔子睡觉

if (Thread.currentThread().getName().equals(“兔子”)&&i%10==0) {

try {

Thread.sleep(1);

} catch (InterruptedException e) {

e.printStackTrace();

}

}

//判断比赛是否结束

boolean flag = gameOver(i);

if (flag) {//若比赛结束就停止程序

break;

}

System.out.println(Thread.currentThread().getName() + “跑了” + i + “步”);

}

}

//判断是否完成比赛

private boolean gameOver(int steps) {

//判断是否有胜利者

if (winner != null) {

return true;

}

{

if (steps >= 100) {

winner = Thread.currentThread().getName();

System.out.println(“胜利者是:” + winner);

return true;

}

}

return false;

}

public static void main(String[] args) {

Race race = new Race();

new Thread(race, “兔子”).start();

new Thread(race, “乌龟”).start();

}

}

在这里插入图片描述

实现Callable接口(了解即可)
  • 实现Callable接口,需要返回值类型

  • 重写call方法,需要抛出异常

  • 创建目标对象

  • 创建执行服务:ExecutorService service = Executors.newFixedThreadPool(3);

  • 提交执行:Future<Boolean> result1 = service.submit(t1);

  • 获取结果:boolean rs1 = result1.get();

  • 关闭服务:service.shutdown();

import org.apache.commons.io.FileUtils;

import java.io.File;

import java.io.IOException;

import java.net.URL;

import java.util.concurrent.*;

//线程创建方式三:实现callable接口

//练习Thread实现一个多线程同步下载图片

public class TestCallable implements Callable {

private String url;//网络图片地址

private String name;//保存的文件名

public TestCallable(String url, String name) {

this.url = url;

this.name = name;

}

//下载图片线程的执行体

@Override

public Boolean call() {

WebDownLoader webDownLoader = new WebDownLoader();

webDownLoader.downLoader(url, name);

System.out.println(“下载了文件,名为:” + name);

return true;

}

public static void main(String[] args) throws ExecutionException, InterruptedException {

TestCallable t1 = new TestCallable(“https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fup.enterdesk.com%2F2021%2Fedpic_source%2F1d%2F31%2F79%2F1d3179f050039cc45f9f62a105b12c3a_8.jpg&refer=http%3A%2F%2Fup.enterdesk.com&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=jpeg?sec=1646039329&t=700647f4c668754644f743467bda0e09”, “1.jpg”);

TestCallable t2 = new TestCallable(“https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fup.enterdesk.com%2F2021%2Fedpic_source%2F1d%2F31%2F79%2F1d3179f050039cc45f9f62a105b12c3a_8.jpg&refer=http%3A%2F%2Fup.enterdesk.com&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=jpeg?sec=1646039329&t=700647f4c668754644f743467bda0e09”, “2.jpg”);

TestCallable t3 = new TestCallable(“https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fup.enterdesk.com%2F2021%2Fedpic_source%2F1d%2F31%2F79%2F1d3179f050039cc45f9f62a105b12c3a_8.jpg&refer=http%3A%2F%2Fup.enterdesk.com&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=jpeg?sec=1646039329&t=700647f4c668754644f743467bda0e09”, “3.jpg”);

//创建执行服务

ExecutorService service = Executors.newFixedThreadPool(3);

//提交执行

  • 27
    点赞
  • 28
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值