线程,进程,多线程
线程创建
[![20km4K.md.png](https://z3.ax1x.com/2021/06/07/20km4K.md.png)](https://imgtu.com/i/20km4K)
继承Thread类
网图下载
package th.demo01;
import org.apache.commons.io.FileUtils;
import java.io.File;
import java.io.IOException;
import java.net.URL;
/**
* @Author 天红
* @Date 2021/6/7 20:04
* @Version 1.0
*/
//练习Thread,实现多线程同步下载图片
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() {
WebDownLLoader webDownLLoader = new WebDownLLoader();
webDownLLoader.downLoad(url,name);
System.out.println("下载了文件名为:"+name);
}
public static void main(String[] args) {
TestThread1 t1 = new TestThread1("https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fpic.jj20.com%2Fup%2Fallimg%2F1114%2F0G520141919%2F200G5141919-2-1200.jpg&refer=http%3A%2F%2Fpic.jj20.com&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=jpeg?sec=1625660613&t=47d43ca821a757183016d42c33ec8b41","1.jpg");
TestThread1 t2 = new TestThread1("https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fclubimg.club.vmall.com%2Fdata%2Fattachment%2Fforum%2F202004%2F28%2F232538icfogvlsgjywjw36.jpg&refer=http%3A%2F%2Fclubimg.club.vmall.com&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=jpeg?sec=1625660613&t=0b38b8beab9576e4a06f51f6c81c70a5","2.jpg");
TestThread1 t3 = new TestThread1("https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fb-ssl.duitang.com%2Fuploads%2Fitem%2F201603%2F04%2F20160304192803_HRdrS.thumb.700_0.jpeg&refer=http%3A%2F%2Fb-ssl.duitang.com&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=jpeg?sec=1625660908&t=1a2a2fb9358036ee12f43e25b1e3564f","3.jpg");
t1.start();
t2.start();
t3.start();
}
}
//下载器
class WebDownLLoader{
// 下载方法
public void downLoad(String url,String name){
try {
FileUtils.copyURLToFile(new URL(url),new File(name));
} catch (IOException e) {
e.printStackTrace();
System.out.println("IO异常");
}
}
}
实现Runnable接口
package th.demo01;
import org.apache.commons.io.FileUtils;
import java.io.File;
import java.io.IOException;
import java.net.URL;
/**
* @Author 天红
* @Date 2021/6/7 20:04
* @Version 1.0
*/
//练习Thread,实现多线程同步下载图片
public class TestThread1 implements Runnable{
private String url;
private String name;
public TestThread1(String url, String name) {
this.url = url;
this.name = name;
}
// 下载图片线程的执行体
@Override
public void run() {
WebDownLLoader webDownLLoader = new WebDownLLoader();
webDownLLoader.downLoad(url,name);
System.out.println("下载了文件名为:"+name);
}
public static void main(String[] args) {
TestThread1 t1 = new TestThread1("https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fpic.jj20.com%2Fup%2Fallimg%2F1114%2F0G520141919%2F200G5141919-2-1200.jpg&refer=http%3A%2F%2Fpic.jj20.com&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=jpeg?sec=1625660613&t=47d43ca821a757183016d42c33ec8b41","1.jpg");
TestThread1 t2 = new TestThread1("https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fclubimg.club.vmall.com%2Fdata%2Fattachment%2Fforum%2F202004%2F28%2F232538icfogvlsgjywjw36.jpg&refer=http%3A%2F%2Fclubimg.club.vmall.com&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=jpeg?sec=1625660613&t=0b38b8beab9576e4a06f51f6c81c70a5","2.jpg");
TestThread1 t3 = new TestThread1("https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fb-ssl.duitang.com%2Fuploads%2Fitem%2F201603%2F04%2F20160304192803_HRdrS.thumb.700_0.jpeg&refer=http%3A%2F%2Fb-ssl.duitang.com&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=jpeg?sec=1625660908&t=1a2a2fb9358036ee12f43e25b1e3564f","3.jpg");
new Thread(t1).start();
new Thread(t2).start();
new Thread(t3).start();
}
}
//下载器
class WebDownLLoader{
// 下载方法
public void downLoad(String url,String name){
try {
FileUtils.copyURLToFile(new URL(url),new File(name));
} catch (IOException e) {
e.printStackTrace();
System.out.println("IO异常");
}
}
}
小节
####
初始并发问题
买火车票例子
package th.demo01;
/**
* @Author 天红
* @Date 2021/6/7 21:01
* @Version 1.0
*/
//多个线程操作同一个对象
// 买火车的例子
// 发现问题:多个线程操作同一个资源的情况下,线程不安全,数据紊乱
public class TestThread2 implements Runnable {
private int ticketNums=10;
@Override
public void run() {
while (true){
if (ticketNums<=0){
break;
}
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName()+"-->拿到了第"+ticketNums--+"票");
}
}
public static void main(String[] args) {
TestThread2 ticket = new TestThread2();
new Thread(ticket,"天红").start();
new Thread(ticket,"老婆").start();
new Thread(ticket,"牛").start();
}
}
龟兔赛跑
package th.demo01;
/**
* @Author 天红
* @Date 2021/6/7 21:29
* @Version 1.0
*/
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 is"+winner);
return true;
}
}
return false;
}
public static void main(String[] args) {
Race race = new Race();
new Thread(race,"兔子").start();
new Thread(race,"乌龟").start();
}
}
实现Callable接口(了解即可)
package th.demo01;
import org.apache.commons.io.FileUtils;
import java.io.File;
import java.io.IOException;
import java.net.URL;
import java.util.concurrent.*;
/**
* @Author 天红
* @Date 2021/6/8 19:40
* @Version 1.0
*/
//callable的好处
//1,可以定义返回值
//2,可以抛出异常
public class TestCallable implements Callable<Boolean> {
private String url;
private String name;
public TestCallable(String url, String name) {
this.url = url;
this.name = name;
}
// 下载图片线程的执行体
@Override
public Boolean call() {
WebDownLLoader webDownLLoader = new WebDownLLoader();
webDownLLoader.downLoad(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%2Fpic.jj20.com%2Fup%2Fallimg%2F1114%2F0G520141919%2F200G5141919-2-1200.jpg&refer=http%3A%2F%2Fpic.jj20.com&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=jpeg?sec=1625660613&t=47d43ca821a757183016d42c33ec8b41", "1.jpg");
TestCallable t2 = new TestCallable("https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fclubimg.club.vmall.com%2Fdata%2Fattachment%2Fforum%2F202004%2F28%2F232538icfogvlsgjywjw36.jpg&refer=http%3A%2F%2Fclubimg.club.vmall.com&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=jpeg?sec=1625660613&t=0b38b8beab9576e4a06f51f6c81c70a5", "2.jpg");
TestCallable t3 = new TestCallable("https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fb-ssl.duitang.com%2Fuploads%2Fitem%2F201603%2F04%2F20160304192803_HRdrS.thumb.700_0.jpeg&refer=http%3A%2F%2Fb-ssl.duitang.com&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=jpeg?sec=1625660908&t=1a2a2fb9358036ee12f43e25b1e3564f", "3.jpg");
// 创建执行服务
ExecutorService service = Executors.newFixedThreadPool(3);
// 提交执行
Future<Boolean> r1 = service.submit(t1);
Future<Boolean> r2 = service.submit(t2);
Future<Boolean> r3 = service.submit(t3);
boolean res1 = r1.get();
boolean res2 = r1.get();
boolean res3 = r1.get();
System.out.println(res1);
System.out.println(res2);
System.out.println(res3);
// 关闭服务
service.shutdown();
}
//下载器
class WebDownLLoader {
// 下载方法
public void downLoad(String url, String name) {
try {
FileUtils.copyURLToFile(new URL(url), new File(name));
} catch (IOException e) {
e.printStackTrace();
System.out.println("IO异常");
}
}
}
}
静态代理模式
package th.demo01;
/**
* @Author 白天红
* @Date 2021/6/8 20:13
* @Version 1.0
*/
//静态代理模式总结:
// 真实对象和代理对象都要实现同一个接口
// 代理角色要代理真实角色
// 好处
//代理对象可以做真实对象做不了的事情
//真实对象专注做自己的事情
public class StaticProxy {
public static void main(String[] args) {
new Thread(()-> System.out.println("我爱你")).start();
// 是不是一样,线程底部就用了静态代理模式
new WeddingCompany(new You()).happyMarry();
}
}
interface Marry{
void happyMarry();
}
//真实角色,你去结婚
class You implements Marry{
@Override
public void happyMarry() {
System.out.println("天红要结婚了,开心