多任务:同一时间做多个任务,吃饭玩手机 多线程:两人打同一个游戏 进程:运行的程序,就是游戏,播放器,qq 线程:一进程多线程,视频中同时有声音,图像和弹幕
步骤:
普通方法和多线程的区别
线程开启不一定立即执行,由CPU调度
public class TestThread1 extends Thread { @Override public void run() { for (int i = 0; i < 20; i++) { System.out.println("run"); } } public static void main(String[] args) { TestThread1 testThread1 = new TestThread1(); testThread1.start(); for (int i = 0; i < 20; i++) { System.out.println("main"); } } }多线程下载图片代码
import org.apache.commons.io.FileUtils; import java.io.File; import java.io.IOException; import java.net.URL; 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) { TestThread2 t1 = new TestThread2("https://pics2.baidu.com/feed/faf2b2119313b07ef031c3a11e36e52495dd8cf7.png?token=105a468f34e282e7cbc96b7fa1951534","1.png"); TestThread2 t2 = new TestThread2("https://img-blog.csdnimg.cn/2020092308391889.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L0pva2VyX0xpZQ==,size_16,color_FFFFFF,t_70#pic_center","2.png"); TestThread2 t3 = new TestThread2("https://img-blog.csdnimg.cn/2020092308404883.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L0pva2VyX0xpZQ==,size_16,color_FFFFFF,t_70#pic_center","3.png"); t1.start(); t2.start(); t3.start(); } } //下载器 class WebDownloader{ public void downloader(String url,String name){ try { FileUtils.copyURLToFile(new URL(url),new File("C:\\Users\\10759\\Desktop\\1\\" + name)); } catch (IOException e) { e.printStackTrace(); System.out.println("IO异常,downloader"); } } }并发问题:多个线程操作同一资源,线程不安全
龟兔赛跑模拟
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的好处: 1.可定义返回值 2.可抛出异常
Thread代理Runable接口,实现start方法
函数式接口:只包含一个抽象方法的接口,可以通过Lamda表达式创建对象