多任务:一个接一个做,不同时
多线程:同时
交替执行,每次执行结果不一样,由cpu调度
package com.liu.www; //1.继承Thread类 2.重写run方法 3.写main主线程 4.new 对象调用它的start方法 public class TestThread extends Thread { @Override public void run() { for (int i = 0; i < 100; i++) { System.out.println("摸摸大 "+i); } } public static void main(String[] args) { //主线程 TestThread testThread = new TestThread(); testThread.start();//start相当于开辟了一条新的线程 for (int i = 0; i < 5000; i++) { System.out.println("0000000"+i); } } }
图片下载练习:
package com.liu.www; 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 file; public TestThread2(String url, String file) { this.url = url; this.file = file; } //下载图片线程的执行体 @Override public void run() { ImgDownload imgDownload = new ImgDownload(); imgDownload.download(url,file); System.out.println("下载了文件,文件名是"+file); } public static void main(String[] args) { TestThread2 t1= new TestThread2("https://pics1.baidu.com/feed/03087bf40ad162d9cbb3cc2d87b712eb8a13cd16?token=ba35ec7e6b5f5aeadb4bea873a4e4b27&s=AD717B8444D13DF50839C8140300B091&f=jpeg","1.jpg"); TestThread2 t2= new TestThread2("https://pics1.baidu.com/feed/1c950a7b02087bf47fe23ffe64bbec2b11dfcf0f?token=39be00f2b209980a21dbaff3c28e1961&s=FEA00DC042E09CE61C38458E0300E002&f=jpeg","2.jpg"); TestThread2 t3= new TestThread2("https://pics1.baidu.com/feed/279759ee3d6d55fb4833a93bfb4af44d21a4dda3?token=7d10a89c5b4a66f2409156fc61feaf13&s=F21F30C48661974F587271110300C0CA&f=jpeg","3.jpg"); t1.start(); t2.start(); t3.start(); } } //下载器类 class ImgDownload{ public void download(String url,String file ){ try { FileUtils.copyURLToFile(new URL(url),new File(file)); } catch (IOException e) { e.printStackTrace(); System.out.println("下载器出现错误"); } } }2.实现Runnable
因为java单继承,推荐使用Runnable,多个线程去 *** 作一个对象
package com.liu.www; //1.继承Thread类 2.重写run方法 3.写main主线程 4.new 线程对象调用它的start方法 public class TestThread3 implements Runnable { @Override public void run() { for (int i = 0; i < 100; i++) { System.out.println("摸摸大 " + i); } } public static void main(String[] args) { //主线程 TestThread3 testThread = new TestThread3(); //主要就是多这一步,new一个thread,把testThread丢进去 Thread thread = new Thread(testThread); thread.start(); for (int i = 0; i < 5000; i++) { System.out.println("0000000" + i); } } }
package com.liu.www; //并发问题: //多个线程同时 *** 作一个对象:火车票的例子 public class TestThread4 implements Runnable { //票数 private int ticketNums=10; @Override public void run() { while (true){ if (ticketNums<=0){ break; }else { 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(); } }3.lamda表达式
函数式接口:只包含一个抽象方法
package com.liu.www; public class Race { //3.定义静态内部类(优化1,类在外面很麻烦) static class baby2 implements interest{ @Override public void inter() { System.out.println("你想要我对lamda感兴趣嘛----two"); } } public static void main(String[] args) { //定义一个接口的实现类 interest baby = new baby(); baby.inter(); baby = new baby2(); baby.inter(); //4.定义局部内部类(优化2,类放在方法里面) class baby3 implements interest{ @Override public void inter() { System.out.println("你想要我对lamda感兴趣嘛----three"); } } baby = new baby3(); baby.inter(); //5.匿名内部类(优化3,没有类名,借助父类或者接口) baby=new interest() { @Override public void inter() { System.out.println("你想要我对lamda感兴趣嘛----four"); } }; baby.inter(); //6.lamba简化 baby=()->{ System.out.println("你想要我对lamda感兴趣嘛----five"); }; baby.inter(); } } //1.首先定义函数式接口 interface interest{ void inter(); } //2.定义一个类去实现这个接口 class baby implements interest{ @Override public void inter() { System.out.println("你想要我对lamda感兴趣嘛"); } } 输出结果: 你想要我对lamda感兴趣嘛 你想要我对lamda感兴趣嘛----two 你想要我对lamda感兴趣嘛----three 你想要我对lamda感兴趣嘛----four 你想要我对lamda感兴趣嘛----five 这个例子是无参数的,有参数的在()->的()里面写参数即可,参数的类型可以省略4.线程五大状态
- 停止线程
-
建议线程通过设置次数自动停止,不建议死循环
-
建议使用标志位
-
jdk官方的不推荐的stop(),destroy()不使用
package com.liu.www;
-
public class Demo_02 implements Runnable{
//1.设置一个标志位 private boolean flag=true; @Override public void run() { int i=0; while (flag){ System.out.println("------------0000000000"+i++); } } //2.设置一个公开的方法停止线程,转换标志位 public void stop(){ this.flag=false; } public static void main(String[] args) { Demo_02 demo_02 = new Demo_02(); new Thread(demo_02).start(); for (int i = 0; i < 10000; i++) { System.out.println("主线程正在执行"+i); if (i==9000){ //调用stop方法切换标志位,让线程停止 demo_02.stop(); System.out.println("线程停止了"); } } }
}
-
线程休眠 sleep() 放大问题的发生性
package com.liu.www; import java.text.SimpleDateFormat; import java.util.Date; public class Demo_03 { public static void main(String[] args) throws InterruptedException { // tendown(); //打印系统当前时间 Date date = new Date(System.currentTimeMillis()); while (true){ Thread.sleep(1000); System.out.println(new SimpleDateFormat("yyyy-MM-dd-HH:mm:ss").format(date)); date = new Date(System.currentTimeMillis()); } } //模拟倒计时 public static void tendown() throws InterruptedException { for (int i = 10; i >= 0; i--) { Thread.sleep(1000); System.out.println(i); } } }
-
线程礼让 yield
package com.liu.www; public class TestYield { public static void main(String[] args) { myyield my = new myyield(); new Thread(my,"a").start(); new Thread(my,"b").start(); } } class myyield implements Runnable{ @Override public void run() { System.out.println(Thread.currentThread().getName()+"线程开始执行"); Thread.yield(); System.out.println(Thread.currentThread().getName()+"线程停止执行"); } 输出结果: a线程开始执行 b线程开始执行 a线程停止执行 b线程停止执行 或者b a线程开始执行 a线程开始执行 b线程停止执行 b线程停止执行
- join() 插队
用户线程:main()
7.线程同步多个线程 *** 作同一个资源
排队解决:就是队列
锁:景区厕所的门锁
线程同步:就是队列+锁 保证线程的安全性
synchronized:同步的
[[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-xOi6D2Xo-1639320833341)(C:Users密西西比的守望AppDataRoamingTyporatypora-user-imagesimage-20210107230030300.png)]
线程不安全:不安全的主要原因在于线程都有各自的内存,互不影响
- 出现负数
- list数据覆盖
第一种方法:synchronized 直接加给方法的 第二种方法:synchronized(obj){ 这个obj是变化的量 增删改 这里写方法 }
JUC并发编程
死锁:
多个线程互相抱着对方需要的资源,然后形成僵持
lock锁:
jdk5开始出现使用 reentantlock:可重复锁
8.线程协作生产者消费者问题:
管程法
信号灯法
9.线程池package com.liu.www; import java.util.concurrent.Executor; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import static java.util.concurrent.Executors.newFixedThreadPool; //测试线程池 public class TestPool { public static void main(String[] args) { //1.创建服务,创建线程池 newFixedThreadPool 参数为线程池的大小 ExecutorService Service = newFixedThreadPool(10); Service.execute(new MyThread()); Service.execute(new MyThread()); Service.execute(new MyThread()); Service.execute(new MyThread()); //2.关闭连接 Service.shutdown(); } } class MyThread implements Runnable{ @Override public void run() { System.out.println(Thread.currentThread().getName()); } } 输出结果: pool-1-thread-1 pool-1-thread-2 pool-1-thread-3 pool-1-thread-4
readPool 参数为线程池的大小
ExecutorService Service = newFixedThreadPool(10);
Service.execute(new MyThread());
Service.execute(new MyThread());
Service.execute(new MyThread());
Service.execute(new MyThread());
//2.关闭连接 Service.shutdown(); }
}
class MyThread implements Runnable{
@Override public void run() { System.out.println(Thread.currentThread().getName()); }
}
输出结果:
pool-1-thread-1
pool-1-thread-2
pool-1-thread-3
pool-1-thread-4
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)