目录
    • 1.继承thread类
    • 2.实现runable接口
                  • 2.同步块synchronized(obj){}

                      多任务、多线程

                      在多任务场景下,两件事看上去同时在做,但实际上,你的大脑在同一时间只做一件事,间隔时间可能很少,但这似乎让你感觉这两件事是同时在做

                      考虑阻塞问题,引入多线程的场景,多线程并发场景

                      程序、进程、线程

                      程序=指令+数据(静态的)
                      在操作系统中运行的程序就是进程,一个进程可以有多个线程
                      比如,看视频时听声音,看图像,看弹幕等

                      学着看jdk文档

                      比如你要看thread
                      你可以搜索,然后阅读

                      往下翻你会看到:

                      线程的创建

                      1.继承thread类

                      //创建线程方式一:继承thread类,重写run方法,调用start()方法开启线程
                      public class testthread1  extends thread{
                      
                          @override
                          public void run() {
                              //run()方法线程体
                              intstream.range(0,20).foreach(i->{
                                  system.out.println("我在看代码"+i);
                              });
                          }
                      
                          public static void main(string[] args) {
                              //创建一个线程对象
                              testthread1 testthread1=new testthread1();
                              //调用start()方法,启动线程,不一定立即执行,由cpu调度执行
                              testthread1.start();
                      
                              //主方法 main方法
                              intstream.range(0,20).foreach(i->{
                                  system.out.println("我在学习多线程"+i);
                              });
                          }
                      }
                      

                      一个小练习:

                      //练习thread实现对线程同步下载图片
                      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() {
                                webdownload webdownload=new webdownload();
                                webdownload.downloader(url,name);
                                system.out.println("下载了文件名:"+name);
                          }
                      
                          public static void main(string[] args) {
                              testthread2 t1=new testthread2("https://profile.csdnimg.cn/b/d/2/3_sxh06","1.jpg");
                              testthread2 t2=new testthread2("https://profile.csdnimg.cn/b/d/2/3_sxh06","2.jpg");
                              testthread2 t3=new testthread2("https://profile.csdnimg.cn/b/d/2/3_sxh06","3.jpg");
                      
                              t1.start();
                              t2.start();
                              t3.start();
                      
                          }
                      }
                      
                      //下载器
                      class webdownload{
                          //下载方法
                          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方法出错");
                              }
                          }
                      }
                      

                      2.实现runable接口

                      //创建线程的方法2:实现runable接口
                      public class testthread3 implements runnable{
                      
                          @override
                          public void run() {
                              //run()方法线程体
                              intstream.range(0,20).foreach(i->{
                                  system.out.println("我在看代码"+i);
                              });
                          }
                      
                          public static void main(string[] args) {
                              //创建一个线程对象
                              testthread3 testthread3=new testthread3();
                              //调用start()方法,启动线程,不一定立即执行,由cpu调度执行
                      //        thread thread=new thread(testthread3);
                      //        thread.start();
                      
                              //或者这样简写
                             new thread(testthread3).start();
                              //主方法 main方法
                              intstream.range(0,100).foreach(i->{
                                  system.out.println("我在学习多线程"+i);
                              });
                          }
                      }
                      

                      理解并发的场景

                      当多个线程使用同一个资源时,会出现问题,看看下面这个买火车票的例子:

                      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 ticket=new testthread4();
                      
                              new thread(ticket,"小明").start();
                              new thread(ticket,"张三").start();
                              new thread(ticket,"李四").start();
                          }
                      }
                      

                      看看运行的结果:

                      可以看到案例中的线程不安全问题,同时数据也是不正确的

                      龟兔赛跑场景

                      /**
                       * 模拟龟兔赛跑
                       */
                      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;
                              }else if (steps >= 100){
                                  winner=thread.currentthread().getname();
                                  system.out.println("胜利者是:"+winner);
                                  return true;
                              }else{
                                  return false;
                              }
                          }
                      
                          public static void main(string[] args) {
                              race race=new race();
                              new thread(race,"兔子").start();
                              new thread(race,"乌龟").start();
                          }
                      }
                      
                      

                      实现callable接口

                      //线程创建方式3
                      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() {
                              com.sxh.thread.webdownload webdownload=new com.sxh.thread.webdownload();
                              webdownload.downloader(url,name);
                              system.out.println("下载了文件名:"+name);
                              return true;
                          }
                      
                          public static void main(string[] args) throws executionexception, interruptedexception {
                              testcallable t1=new testcallable("https://profile.csdnimg.cn/b/d/2/3_sxh06","1.jpg");
                              testcallable t2=new testcallable("https://profile.csdnimg.cn/b/d/2/3_sxh06","2.jpg");
                              testcallable t3=new testcallable("https://profile.csdnimg.cn/b/d/2/3_sxh06","3.jpg");
                      
                              //创建执行服务
                              executorservice ser= executors.newfixedthreadpool(3);
                              //提交执行
                              future<boolean> r1=ser.submit(t1);
                              future<boolean> r2=ser.submit(t2);
                              future<boolean> r3=ser.submit(t3);
                              //获取结果
                              boolean rs1=r1.get();
                              boolean rs2=r2.get();
                              boolean rs3=r3.get();
                              //关闭服务
                              ser.shutdownnow();
                          }
                      
                      }
                      

                      理解函数式接口

                      任何接口,只包含唯一一个抽象方法,就是函数式接口

                      /**
                       * lambdab表达式的发展
                       */
                      public class testlambda1 {
                          //3.静态内部类
                          static class like2 implements ilike{
                              @override
                              public void lambda() {
                                  system.out.println("i like lambda2");
                              }
                          }
                      
                          public static void main(string[] args) {
                              ilike like=new like();
                              like.lambda();
                      
                              like=new like2();
                              like.lambda();
                      
                              //4.局部内部类
                             class like3 implements ilike{
                                  @override
                                  public void lambda() {
                                      system.out.println("i like lambda3");
                                  }
                              }
                              like=new like3();
                              like.lambda();
                      
                              //5.匿名内部类
                              like=new ilike() {
                                  @override
                                  public void lambda() {
                                      system.out.println("i like lambda4");
                                  }
                              };
                              like.lambda();
                      
                              //6.用lambda简化
                              like=()->{
                                  system.out.println("i like lambda5");
                              };
                              like.lambda();
                          }
                      }
                      
                      //1.定义一个函数式接口
                      interface ilike{
                          void lambda();
                      }
                      
                      //2.实现类
                      class like implements ilike{
                      
                          @override
                          public void lambda() {
                              system.out.println("i like lambda");
                          }
                      }
                      

                      理解线程的状态

                      线程停止

                      public class teststop implements runnable{
                      
                          //1.设置一个标志位
                          private boolean flag=true;
                          @override
                          public void run() {
                             int i=0;
                             while (flag){
                                 system.out.println("run...thread.."+i++);
                             }
                          }
                      
                          //2.设置一个公开的方法停止线程,转换标志位
                          public void stop(){
                                 this.flag=false;
                          }
                      
                      
                          public static void main(string[] args) {
                              teststop stop=new teststop();
                              new thread(stop).start();
                      
                      
                              for (int i = 0; i < 1000; i++) {
                                  system.out.println("main"+i);
                                  if (i==900){
                                      //调用stop方法,让线程停止
                                      stop.stop();
                                      system.out.println("线程该停止了");
                                  }
                              }
                      //        intstream.range(0,1000).foreach(i->{
                      //            
                      //        });
                          }
                      }
                      

                      线程休眠sleep

                      每个对象都有一把锁,sleep不会释放锁

                      1.网路延迟

                                  //模拟延迟
                                  try {
                                      thread.sleep(200); //ms
                                  } catch (interruptedexception e) {
                                      e.printstacktrace();
                                  }
                      

                      2.倒计时等

                       public static void main(string[] args) {
                             try {
                                  tendown();
                              } catch (interruptedexception e) {
                                  e.printstacktrace();
                             }
                        }
                          public static void tendown() throws interruptedexception {
                              int num=10;
                              while (true){
                                  thread.sleep(1000);
                                  system.out.println(num--);
                                  if(num<=0)
                                  {
                                      break;
                                  }
                              }
                          }
                      
                       public static void main(string[] args) {
                              //打印系统当前时间
                              date starttime=new date(system.currenttimemillis());
                              while (true){
                                  try {
                                      thread.sleep(1000);
                                      system.out.println(new simpledateformat("hh:mm:ss").format(starttime));
                                      starttime=new date(system.currenttimemillis());//更新时间
                                  } catch (interruptedexception e) {
                                      e.printstacktrace();
                                  }
                              }
                          }
                      

                      线程礼让yield

                      //线程礼让  礼让不一定成功,由cpu重新调度
                      public class testyield {
                          public static void main(string[] args) {
                              myyield myyield=new myyield();
                              new thread(myyield,"a").start();
                              new thread(myyield,"b").start();
                          }
                      }
                      class myyield implements  runnable{
                      
                          @override
                          public void run() {
                              system.out.println(thread.currentthread().getname()+"线程开始执行");
                              thread.yield();
                              system.out.println(thread.currentthread().getname()+"线程停止执行");
                          }
                      }
                      

                      线程强制执行

                      //测试join方法  想象为插队
                      public class testjoin implements  runnable{
                          @override
                          public void run() {
                              for (int i = 0; i < 100; i++) {
                                  system.out.println("线程vip来了"+i);
                              }
                          }
                      
                          public static void main(string[] args) throws interruptedexception {
                              //启动线程
                              testjoin testjoin=new testjoin();
                              thread thread=new thread(testjoin);
                              thread.start();
                      
                              //主线程
                              for (int i = 0; i < 1000; i++) {
                                  if (i==200){
                                      thread.join(); //插队
                                  }
                                  system.out.println("main"+i);
                              }
                          }
                      }
                      

                      观察线程状态

                      public class teststate {
                          public static void main(string[] args) throws interruptedexception {
                              thread thread=new thread(()->{
                                  for (int i = 0; i < 5; i++) {
                                      try {
                                          thread.sleep(1000);
                                      } catch (interruptedexception e) {
                                          e.printstacktrace();
                                      }
                                  }
                                  system.out.println("//");
                              });
                      
                              //观察状态
                              thread.state state=thread.getstate();
                              system.out.println(state);   //new
                      
                              //启动后
                              thread.start();
                              state=thread.getstate();
                              system.out.println(state);   //run
                      
                              while (state != thread.state.terminated)
                              {
                                  thread.sleep(100);
                                  state=thread.getstate();//更新线程状态
                                  system.out.println(state);   //run
                              }
                          }
                      }
                      

                      线程的优先级

                      //测试线程的优先级
                      public class testpriority {
                          public static void main(string[] args) {
                              //主线程默认优先级
                              system.out.println(thread.currentthread().getname()+"--->"+thread.currentthread().getpriority());
                      
                              mypriority mypriority=new mypriority();
                      
                              thread t1=new thread(mypriority);
                              thread t2=new thread(mypriority);
                              thread t3=new thread(mypriority);
                              thread t4=new thread(mypriority);
                              thread t5=new thread(mypriority);
                              thread t6=new thread(mypriority);
                              //先设置优先级,在启动
                              t1.start();
                              t2.setpriority(1);
                              t2.start();
                              t3.setpriority(4);
                              t3.start();
                              t4.setpriority(thread.max_priority);
                              t4.start();
                              t5.setpriority(-1);
                              t5.start();
                              t6.setpriority(11);
                              t6.start();
                      
                          }
                      }
                      class mypriority implements runnable{
                      
                          @override
                          public void run() {
                              system.out.println(thread.currentthread().getname()+"--->"+thread.currentthread().getpriority());
                          }
                      }
                      

                      守护线程

                      线程分为用户线程和守护线程

                      //测试守护线程
                      public class testdaemon {
                          public static void main(string[] args) {
                              god god=new god();
                              you you=new you();
                              thread thread=new thread(god);
                              thread.setdaemon(true); //默认是false表示用户线程
                              thread.start();
                      
                              new thread(you).start();
                      
                          }
                      }
                      
                      class god implements  runnable{
                      
                          @override
                          public void run() {
                            while (true){
                                system.out.println("上帝保佑着你");
                            }
                          }
                      }
                      class you implements runnable{
                          @override
                          public void run() {
                              for (int i = 0; i < 36000; i++) {
                                  system.out.println("你活着"+i);
                              }
                              system.out.println("goodbye!!");
                          }
                      }
                      

                      线程同步机制

                      解决安全性问题:队列+锁

                      1.synchronized 同步方法

                      默认锁的是this,如需锁其他的,使用下面的同步块

                      //synchronized 同步方法
                          private  synchronized void buy(){
                              if (ticketnums<=0){
                                  flag=false;
                                  return;
                              }
                              //模拟延迟
                              try {
                                  thread.sleep(100);
                              } catch (interruptedexception e) {
                                  e.printstacktrace();
                              }
                              //买票
                              system.out.println(thread.currentthread().getname()+"-->拿到了第"+ticketnums--+"张票");
                          }
                      

                      2.同步块synchronized(obj){}

                      锁的对象是变化的量,需要增删改的对象
                      obj称之为同步监视器,即监视对象

                      public class unsafelist {
                          public static void main(string[] args) {
                              list<string> list=new arraylist<string>();
                              for (int i = 0; i < 10000; i++) {
                                  new thread(()->{
                                      synchronized (list){
                                          list.add(thread.currentthread().getname());
                                      }
                                  }).start();
                              }
                      
                              try {
                                  thread.sleep(3000);
                              } catch (interruptedexception e) {
                                  e.printstacktrace();
                              }
                              system.out.println(list.size());
                          }
                      }
                      

                      lock

                      class a{
                           //reentrantlock 可重入锁
                           private final reentrantlock lock=new reentrantlock();
                           public void f(){
                             lock.lock();//加锁
                             try{
                                 //.....
                              }
                             finally{
                                lock.unlock();//释放锁
                              }
                           }
                         
                      }
                      
                      
                      

                      synchronized与lock

                      1. lock是显示锁需要手动开关,synchronized是隐式锁,出了作用域自动释放
                      2. lock只有代码块锁,synchronized有代码块锁和方法锁
                      3. jvm将花费更少的时间来调度线程,性能更好,更有扩展性
                      4. 优先使用:lock>同步代码块>同步方法

                      到此这篇关于java多线程学习笔记的文章就介绍到这了,更多相关java 多线程内容请搜索www.887551.com以前的文章或继续浏览下面的相关文章希望大家以后多多支持www.887551.com!