ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

Java核心类库——线程

2021-06-18 21:35:18  阅读:146  来源: 互联网

标签:类库 Java Thread void run 线程 new public


一:多线程技术的概述:

1.直接看截图:

 

 

 

 电脑只能干一件事情,学习多线程的意义在于让多个路径更合理的交替执行。CPU的高速切换给我们一种多个线程在同时执行的假象。

 

 

2.

 

 

 

 二:线程讲解:

1.多线程的第一种实现方式:

1.1)该类要实现Tread进程

1.2)代码演示:

进程1的类:

1 public class MyThread extends Thread{
2     @Override
3     public void run() {
4         for(int i = 0;i<10;i++){
5             System.out.println("汗滴禾下土"+i);
6         }
7     }
8 }

Main()方法:

 1 public class Demo01 {
 2     public static void main(String[] args) {
 3         //创建线程对象
 4         MyThread thread = new MyThread();
 5         //启动线程
 6         thread.start();
 7         for(int i = 0;i<10;i++){
 8             System.out.println("锄禾日当午"+i);
 9         }
10     }
11 }

一下是对上述代码的解释:

 

 由一个线程调用的方法,该方法也会执行在这个线程中

 

 2.线程的第二种实现方式:

2.1)实现Runnable()接口

2.2)代码演示:

线程1:

 1 /**
 2  * 用于给线程执行的任务
 3  */
 4 public class MyRunnable implement Runnable{
 5     @Override
 6     public void run() {
 7         for(int i = 0;i<10;i++){
 8             System.out.println("汗滴禾下土"+i);
 9         }
10     }
11 }

主线程(Main方法):

 1 public class Demo01 {
 2     public static void main(String[] args) {
 3         //1.创建一个任务对象
 4         MyRunnable runnable = new MyRunnable();
 5         //2.创建一个线程对象,并给他一个任务
 6         Thread t = new Thread(runnable);
 7         //3.启动线程
 8         t.start();
 9         for(int i = 0;i<10;i++){
10             System.out.println("锄禾日当午"+i);
11         }
12     }
13 }

打印的结果同上面相同

3.实现线程的两种方式中,实现Runnable接口的优势:

 

 虽然Runnable接口很有优势,但也会使用继承Thread,因为它可以创建线程很方便:

 1 public class Demo02 {
 2     public static void main(String[] args) {
 3         //采用匿名内部类的方式创建线程
 4        new Thread(){
 5            @Override
 6            public void run() {
 7                for(int i = 0;i<10;i++){
 8                    System.out.println("锄禾日当午"+i);
 9                }
10            }
11        }.start();
12         for(int i = 0;i<10;i++){
13             System.out.println("汗滴禾下土"+i);
14         }
15     }
16 }

4.线程中常见的方法

1.常见的构造方法

 

 (name是给线程起的名字)

2.常用的方法:

2.1)getName();获取线程的名字

2.2)  getPriority();获取线程的优先级

2.3)getStatic();获取线程的状态

2.4)isAlive();判断该线程是否活着

2.5)isDaemon();判断该线程是否为守护线程

2.6)sleep(long millis);让线程休眠多长的时间

2.7)sleep(lont millis,int nanos);

2.8)start();开始线程

2.9)

 2.10)

 

 

3.线程技术的代码演示:

一:获取和设置线程的名称:

 1 public class Demo02 {
 2     public static void main(String[] args) {
 3         //首先打印出主程序的名称
 4         System.out.println(Thread.currentThread().getName());
 5         //采用匿名内部类的方式创建一个线程
 6         new Thread(new MyRunnable(),"谁知盘中餐").start();
 7 
 8     }
 9     //创建一个静态的内部类
10     static class MyRunnable implements Runnable{
11 
12         @Override
13         public void run() {
14             System.out.println(Thread.currentThread().getName());
15         }
16     }
17 }

currentThread()获取当前的线程,返回的是一个线程

二:线程休眠sleep();

1 public class Demo02 {
2     public static void main(String[] args) throws InterruptedException {
3        for(int i = 0;i<10;i++){
4            System.out.println(i);
5            Thread.sleep(1000);
6        }
7     }
8 }

3.3)线程阻塞:可以理解为比较消耗时间的操作,比如一个线程要执行100行代码,其中有十行代码是读取文件,这个过程花费了比较多的时间,可以认为是线程阻塞。

                        常见的线程阻塞有读取文件,等待用户输入等

 1 public class Demo02 {
 2     /**
 3      * 需求:我想在Main()方法结束后终端子程序
 4      * 1.为子程序打一个标记
 5      * 2.在任务类中catch()块中处理
 6      * @param args
 7      * @throws InterruptedException
 8      */
 9     public static void main(String[] args) throws InterruptedException {
10         Thread t = new Thread(new MyRunnable());
11         t.start();
12         for(int i = 0;i<5;i++){
13             System.out.println(Thread.currentThread().getName()+":"+i);
14         }
15         //1.为子程序打一个标记
16         t.interrupt();
17     }
18     static class MyRunnable implements Runnable{
19 
20         @Override
21         public void run() {
22             for(int i = 0;i<10;i++){
23                 System.out.println(Thread.currentThread().getName()+":"+i);
24                 try {
25                     Thread.sleep(1000);
26                 } catch (InterruptedException e) {
27                    // e.printStackTrace();
28                     //2.在任务类中catch()块中处理
29                     System.out.println("你可以去死掉了");
30                     return;//结束该线程任务
31                 }
32             }
33         }
34     }
35 }

 

 四:守护线程:

 

 

 守护线程在启动线程之前设置

 1 public class Demo02 {
 2     /**
 3      * 需求:我想在Main()方法结束后终端子程序
 4      * 1.为子程序打一个标记
 5      * 2.在任务类中catch()块中处理
 6      * @param args
 7      * @throws InterruptedException
 8      */
 9     public static void main(String[] args) throws InterruptedException {
10         Thread t = new Thread(new MyRunnable());
11         //将他设置为守护线程
12         t.setDaemon(true);
13         t.start();
14         for(int i = 0;i<5;i++){
15             System.out.println(Thread.currentThread().getName()+":"+i);
16             Thread.sleep(1000);
17         }
18     }
19     static class MyRunnable implements Runnable{
20 
21         @Override
22         public void run() {
23             for(int i = 0;i<10;i++){
24                 System.out.println(Thread.currentThread().getName()+":"+i);
25                 try {
26                     Thread.sleep(1000);
27                 } catch (InterruptedException e) {
28                    // e.printStackTrace();
29                     //2.在任务类中catch()块中处理
30                     System.out.println("你可以去死掉了");
31                     return;//结束该线程任务
32                 }
33             }
34         }
35     }
36 }

提取出来就是这个样子:

1  Thread t = new Thread(new MyRunnable());
2          //将他设置为守护线程
3          t.setDaemon(true);
4          t.start();

五:线程安全问题:

1.线程不安全:当多个线程异步处理同一个数据时,会导致数据不安全问题

2.1)代码演示(买票)

 1 public class Dem01 {
 2     public static void main(String[] args) {
 3         //创建任务对象
 4         Runnable run = new saleTicket();
 5         //一个任务被多个线程执行
 6         Thread t1 = new Thread(run);
 7         Thread t2 = new Thread(run);
 8         Thread t3 = new Thread(run);
 9         //启动线程
10         t1.start();
11         t2.start();
12         t3.start();
13 
14     }
15     /**
16      * 写一个任务类,进行卖票
17      */
18     static class saleTicket implements Runnable{
19         private //票的数量
20                 int count = 10;
21         @Override
22         public void run() {
23             while (count > 0) {
24                 System.out.println("正在售票");
25                 try {
26                     Thread.sleep(1000);
27                 } catch (InterruptedException e) {
28                     e.printStackTrace();
29                 }
30                 count--;
31                 System.out.println("还有余票" + count);
32             }
33         }
34     }
35 }

 

 这个结果显然是不合理的,原因:当只剩最后一张票时,线程A先抢到时间戳,进入循环,此时她改变了count的数量变为0,但是,此时在他还没有跳出循环的时候,线程B C 都进来了,就这导致后面出现余票-1 -2的现象。

2.线程安全1——同步代码块synchronized

2.1)语法:synchronized(同一个对象){  排队执行的代码块 }

2.1)代码演示(对买票系统的改进)

 1 public class Dem01 {
 2     public static void main(String[] args) {
 3         //创建任务对象
 4         Runnable run = new saleTicket();
 5         //一个任务被多个线程执行
 6         Thread t1 = new Thread(run);
 7         Thread t2 = new Thread(run);
 8         Thread t3 = new Thread(run);
 9         //启动线程
10         t2.start();
11         t1.start();
12         t3.start();
13 
14     }
15 
16     /**
17      * 写一个任务类,进行卖票
18      */
19     static class saleTicket implements Runnable {
20         //票的数量
21         private int count = 10;
22         //创建一个对象,作为锁
23         private Object o = new Object();
24         @Override
25         public void run() {
26             while (true) {
27                 synchronized (o) {
28                     if (count > 0) {
29                         System.out.println("正在售票");
30                         try {
31                             Thread.sleep(1000);
32                         } catch (InterruptedException e) {
33                             e.printStackTrace();
34                         }
35                         count--;
36                         System.out.println(Thread.currentThread().getName()+":还有余票" + count);
37                     } else {
38                         break;
39                     }
40                 }
41             }
42         }
43     }
44 }

谁的线程先启动,谁就先抢到时间戳,在后续中也会较快抢到时间戳,因为他离锁最近

3.线程安全2——同步方法:

3.1)在任务类中,将方法代码块抽去出来,将方法用synchronized修饰

3.2)代码演示(对买票的修改)

 1 public class Dem01 {
 2     public static void main(String[] args) {
 3         //创建任务对象
 4         Runnable run = new saleTicket();
 5         //一个任务被多个线程执行
 6         Thread t1 = new Thread(run);
 7         Thread t2 = new Thread(run);
 8         Thread t3 = new Thread(run);
 9         //启动线程
10         t2.start();
11         t1.start();
12         t3.start();
13 
14     }
15 
16     /**
17      * 写一个任务类,进行卖票
18      */
19     static class saleTicket implements Runnable {
20         //票的数量
21         private int count = 10;
22         @Override
23         public void run() {
24             while (true) {
25                 boolean flag = sale();
26                 if(!flag){
27                     break;
28                 }
29             }
30         }
31         public synchronized boolean sale(){
32             if (count > 0) {
33                 System.out.println("正在售票");
34                 try {
35                     Thread.sleep(1000);
36                 } catch (InterruptedException e) {
37                     e.printStackTrace();
38                 }
39                 count--;
40                 System.out.println(Thread.currentThread().getName()+":还有余票" + count);
41                 return true;
42             }
43             return false;
44         }
45     }
46 }

同步方法的锁对象就是创建该类的对象,就像是Runnable run = new saleTicket();只创建了一个任务,所有为同一把锁

当同步代码块和同步方法同时上锁是,只有当一个锁里面完成后,才可以执行下一个锁,就像两个试衣间只有一个门一样

 

4.线程安全3——显示锁Lock:

4.1)自己创建一个锁对象。锁Lock 类,他的子类reentrantLock

4.2)Lock l = new reentrantLock();   l.lock()上锁     l.unlock()解锁

4.3)代码演示(对售票的改进)

 1 import java.util.concurrent.locks.Lock;
 2 import java.util.concurrent.locks.ReentrantLock;
 3 
 4 public class Dem01 {
 5     public static void main(String[] args) {
 6         //创建任务对象
 7         Runnable run = new saleTicket();
 8         //一个任务被多个线程执行
 9         Thread t1 = new Thread(run);
10         Thread t2 = new Thread(run);
11         Thread t3 = new Thread(run);
12         //启动线程
13         t2.start();
14         t1.start();
15         t3.start();
16 
17     }
18 
19     /**
20      * 写一个任务类,进行卖票
21      */
22     static class saleTicket implements Runnable {
23         //票的数量
24         private int count = 10;
25         //创建锁对象
26         private Lock l = new ReentrantLock();
27         
28         @Override
29         public void run() {
30             while (true) {
31                 //对需要排队的代码块进行上锁
32                 l.lock();
33                 if (count > 0) {
34                     System.out.println("正在售票");
35                     try {
36                         Thread.sleep(1000);
37                     } catch (InterruptedException e) {
38                         e.printStackTrace();
39                     }
40                     count--;
41                     System.out.println(Thread.currentThread().getName() + ":还有余票" + count);
42                 } else {
43                     break;
44                 }
45                 //代码块执行完后解锁
46                 l.unlock();
47             }
48         }
49     }
50 }

 

5.显示锁和隐式锁的区别

5.1)定义:隐式锁(Synchronized)是Java的关键字,当它用来修饰一个方法或一个代码块时,能够保证在同一时刻最多只有一个线程执行该代码。因为当调用                               Synchronized修饰的代码时,并不需要显示的加锁和解锁的过程,所以称之为隐式锁。
                   显示锁(Lock)是一个接口,提供了无条件的、可轮询的、定时的、可中断的锁获取操作,所有的加锁和解锁操作方法都是显示的,因而称为显示锁。
5.2)区别:(9条消息) 隐式锁与显示锁的区别_ZL_do_it的博客-CSDN博客_显示锁和隐式锁

 

6.公平锁和非公平锁:公平锁是谁先来排队,谁就先解锁,非公平锁就是谁先抢到谁就先解锁。Java中默认的为非公平锁,如何在Java中构建公平锁:在显示锁中创                                          建 锁对象时,Lock l = new ReentrantLock(true);添加true

7.线程死锁:

7.1)线程死锁的原因:

7.2)代码演示:警察对罪犯说,你放了人质,我放了你;罪犯对警察说,你放了我,我放了人质。

 1 public class Demo02 {
 2     /**
 3      * 创建了两个线程,两个线程都在等待对方的回答,很有可能造成线程死锁。
 4      * @param args
 5      */
 6     public static void main(String[] args) {
 7         //创建警察和罪犯对象
 8         Culprit c = new Culprit();
 9         Police p = new Police();
10         //罪犯说话想要得到警察回应
11         c.say(p);
12         //创建线程对象
13         new MyTread(c,p).start();
14     }
15 
16     static class MyTread extends Thread{
17         private Culprit c;
18         private Police p;
19 
20         public MyTread(Culprit c,Police p){
21             this.c = c;
22             this.p = p;
23         }
24         @Override
25         public void run() {
26             p.say(c);
27         }
28     }
29     static class Culprit{
30         //罪犯对警察说的话
31         //罪犯对警察说了话之后要得到警察的回应
32         public synchronized void say(Police p){
33             System.out.println("你放了我,我放了罪犯");
34             p.fun();
35         }
36         //罪犯回应警察的话
37         public synchronized void fun(){
38             System.out.println("我把人质留下,你放了我");
39         }
40     }
41 
42     static class Police{
43         //警察对罪犯说的话
44         //警察在说完话之后要得到罪犯的回应
45         public synchronized void say(Culprit c){
46             System.out.println("你放了人质,我放了你");
47             c.fun();
48         }
49         //警察回应罪犯
50         public synchronized void fun(){
51             System.out.println("把人质留下,你可以走了");
52         }
53     }
54 }

7.3)如何避免线程死锁:在任何可能导致锁产生的方法里面,不要在调用其他有可能产生锁的方法。不然的话极有可能产生死锁的问题。

8.多线程通信问题:

8.1)举个栗子来描述一下场景:A线程去下载音乐,B线程要播放音乐,如何让A线程现在完音乐后去告诉B线程你可以播放了,这就涉及到多线程间的通信问题。

8.2)涉及这个问题时常用的方法:Object类中关于线程问题的方法:

 

 

8.3)代码演示(生产者和消费者的关系):这里用厨师和服务员之间的关系来体现他。厨师做菜的时候,让服务员这条线程休眠,厨师做好饭后,唤醒服务员,让他去上菜,这个时候厨师休眠,等服务员端回盘子,唤醒厨师,让他做菜,服务员再次休眠。就这样循环。

  1 public class Demo03 {
  2     /**
  3      * 这是一个生产者和消费者两个线程之间的关系,厨师生产一份饭,服务员端走一份,为了让他们工作有序,就要让一个在工作时,
  4      * 另一个在睡觉
  5      *
  6      * @param args
  7      */
  8     public static void main(String[] args) {
  9         //创建类对象
 10         Food f = new Food();
 11         Cook c = new Cook(f);
 12         c.start();
 13         Waiter w = new Waiter(f);
 14         w.start();
 15 
 16     }
 17 
 18     static class Food {
 19         private String name;
 20         private String taste;
 21 
 22         //true为做饭
 23         private boolean flag = true;
 24 
 25         //厨师做饭
 26         public void setNameAndTaste(String name, String taste) {
 27             if (flag) {
 28                 this.name = name;
 29                 try {
 30                     Thread.sleep(1000);
 31                 } catch (InterruptedException e) {
 32                     e.printStackTrace();
 33                 }
 34                 this.taste = taste;
 35                 flag = false;
 36 
 37                 //唤醒所有休眠的线程
 38                 this.notifyAll();
 39                 try {
 40                     //做好饭之后睡去,等待服务员唤醒
 41                     this.wait();
 42                 } catch (InterruptedException e) {
 43                     e.printStackTrace();
 44                 }
 45             }
 46         }
 47 
 48         //服务员获取菜
 49         public void getFood() {
 50             if (!flag) {
 51                 try {
 52                     Thread.sleep(1000);
 53                 } catch (InterruptedException e) {
 54                     e.printStackTrace();
 55                 }
 56                 System.out.println("菜的名字是:" + name + ",味道是:" + taste);
 57                 flag = true;
 58                 this.notifyAll();
 59                 try {
 60                     this.wait();
 61                 } catch (InterruptedException e) {
 62                     e.printStackTrace();
 63                 }
 64             }
 65         }
 66     }
 67 
 68     static class Cook extends Thread {
 69         private Food f;
 70 
 71         public Cook(Food f) {
 72             this.f = f;
 73         }
 74 
 75         @Override
 76         public void run() {
 77             for (int i = 0; i < 10; i++) {
 78                 if (i % 2 == 0) {
 79                     f.setNameAndTaste("老干妈小米粥", "香辣味");
 80                 } else {
 81                     f.setNameAndTaste("煎饼果子", "甜辣味");
 82                 }
 83             }
 84         }
 85 
 86     }
 87 
 88     static class Waiter extends Thread {
 89         private Food f;
 90 
 91         public Waiter(Food f) {
 92             this.f = f;
 93         }
 94 
 95         @Override
 96         public void run() {
 97             for (int i = 0; i < 10; i++) {
 98                 f.getFood();
 99             }
100         }
101     }
102 
103 }

9.线程的六种状态:

 

10.带返回值的线程Callable

10.1)这是一个接口

10.2)代码演示如何使 1 import java.util.concurrent.Callable; 2 import java.util.concurrent.ExecutionExcepti 3 import java.util.concurrent.FutureTask;

 4 
 5 public class Demo04 {
 6     public static void main(String[] args) throws ExecutionException, InterruptedException {
 7         //2.创建一个Callable对象
 8         Callable<Integer> C = new MyCallable();
 9         //3.创建一个任务对象
10         FutureTask<Integer> f = new FutureTask<>(C);//f.isDone()判断线程是否已经执行完了;f.cancel(true/false);决定是否取消线程,返回布尔类型
11 //4.创建一个线程对象,将任务传给他 12 new Thread(f).start(); 13 //当Callable线程调用了get方法后,主程序main就要等到子程序执行完后,得到一个返回值后,才可以执行 14 Integer j = f.get(); 15 System.out.println(j); 16 for(int i = 0;i<10;i++){ 17 Thread.sleep(100); 18 System.out.println(i); 19 } 20 } 21 22 //1.创建一个类,实现Callable<T>接口,注意他是泛型的 23 static class MyCallable implements Callable<Integer> { 24 25 @Override 26 public Integer call() throws Exception { 27 for(int i = 0;i<10;i++){ 28 Thread.sleep(100); 29 System.out.println(i); 30 } 31 return 100; 32 } 33 } 34 }

11.线程池:

1.概述:就是用来盛放线程的

 2.线程池的底层原理之一

 

3.线程池的分类

1.缓存线程池

 

 

 1.2)代码演示

 1 import java.util.concurrent.*;
 2 
 3 public class Demo05 {
 4     public static void main(String[] args) {
 5         //1.创建线程池对象
 6         ExecutorService service = Executors.newCachedThreadPool();
 7         //2.向线程池中添加新的任务并且执行他
 8         service.execute(new Runnable() {
 9             @Override
10             public void run() {
11                 System.out.println(Thread.currentThread().getName()+":"+"锄禾日当午");
12             }
13         });
14         service.execute(new Runnable() {
15             @Override
16             public void run() {
17                 System.out.println(Thread.currentThread().getName()+":"+"锄禾日当午");
18             }
19         });
20         service.execute(new Runnable() {
21             @Override
22             public void run() {
23                 System.out.println(Thread.currentThread().getName()+":"+"锄禾日当午");
24             }
25         });
26 
27         //让主线程休眠1秒钟,此时上述线程空闲,则不会在扩容,而用原来的线程
28         try {
29             Thread.sleep(1000);
30         } catch (InterruptedException e) {
31             e.printStackTrace();
32         }
33         service.execute(new Runnable() {
34             @Override
35             public void run() {
36                 System.out.println(Thread.currentThread().getName()+":"+"锄禾日当午");
37             }
38         });
39     }
40 }

 

 

2.定长线程池

 

 代码演示

 1 import java.util.concurrent.*;
 2 
 3 public class Demo05 {
 4     public static void main(String[] args) {
 5         //1.创建线程池对象
 6         ExecutorService service = Executors.newFixedThreadPool(2);
 7         //2.向线程池中添加新的任务并且执行他
 8         service.execute(new Runnable() {
 9             @Override
10             public void run() {
11                 System.out.println(Thread.currentThread().getName()+":"+"锄禾日当午");
12                 try {
13                     Thread.sleep(3000);
14                 } catch (InterruptedException e) {
15                     e.printStackTrace();
16                 }
17             }
18         });
19         service.execute(new Runnable() {
20             @Override
21             public void run() {
22                 System.out.println(Thread.currentThread().getName()+":"+"锄禾日当午");
23                 try {
24                     Thread.sleep(3000);
25                 } catch (InterruptedException e) {
26                     e.printStackTrace();
27                 }
28             }
29         });
30         service.execute(new Runnable() {
31             @Override
32             public void run() {
33                 System.out.println(Thread.currentThread().getName()+":"+"锄禾日当午");
34             }
35         });
36 
37         //让主线程休眠1秒钟,此时上述线程空闲,则不会在扩容,而用原来的线程
38         try {
39             Thread.sleep(1000);
40         } catch (InterruptedException e) {
41             e.printStackTrace();
42         }
43         service.execute(new Runnable() {
44             @Override
45             public void run() {
46                 System.out.println(Thread.currentThread().getName()+":"+"锄禾日当午");
47             }
48         });
49     }
50 }

 

 

3.单线程线程池

 

 

 1 import java.util.concurrent.*;
 2 
 3 public class Demo05 {
 4     public static void main(String[] args) {
 5         //1.创建线程池对象
 6         ExecutorService service =Executors.newSingleThreadExecutor();
 7         //2.向线程池中添加新的任务并且执行他
 8         service.execute(new Runnable() {
 9             @Override
10             public void run() {
11                 System.out.println(Thread.currentThread().getName()+":"+"锄禾日当午");
12                 try {
13                     Thread.sleep(3000);
14                 } catch (InterruptedException e) {
15                     e.printStackTrace();
16                 }
17             }
18         });
19         service.execute(new Runnable() {
20             @Override
21             public void run() {
22                 System.out.println(Thread.currentThread().getName()+":"+"锄禾日当午");
23                 try {
24                     Thread.sleep(3000);
25                 } catch (InterruptedException e) {
26                     e.printStackTrace();
27                 }
28             }
29         });
30 
31         //让主线程休眠1秒钟,此时上述线程空闲,则不会在扩容,而用原来的线程
32         try {
33             Thread.sleep(1000);
34         } catch (InterruptedException e) {
35             e.printStackTrace();
36         }
37         service.execute(new Runnable() {
38             @Override
39             public void run() {
40                 System.out.println(Thread.currentThread().getName()+":"+"锄禾日当午");
41             }
42         });
43     }
44 }

 

 

4.周期定长线程池

 

 4.1)定时执行一次

 

 在5秒后会打印出 “锄禾日当午”

 1 import java.util.concurrent.*;
 2 
 3 public class Demo05 {
 4     public static void main(String[] args) {
 5         ScheduledExecutorService service = Executors.newScheduledThreadPool(2);
 6         service.schedule(new Runnable() {
 7             @Override
 8             public void run() {
 9                 System.out.println("锄禾日当午");
10             }
11         },5,TimeUnit.SECONDS);
12     }
13 }

4.2)周期定长执行任务

 

 

 1 import java.util.concurrent.*;
 2 
 3 public class Demo05 {
 4     public static void main(String[] args) {
 5         ScheduledExecutorService service = Executors.newScheduledThreadPool(2);
 6         service.scheduleAtFixedRate(new Runnable() {
 7             @Override
 8             public void run() {
 9                 System.out.println("汗滴禾下土");
10             }
11         },5,2,TimeUnit.SECONDS);
12     }
13 }

 

十二:lambda表达式:

1.函数式编程思想

2.格式:Thread t = new Thread((我是参数) ->{我是方法体});

3.仅用来实现接口,实现的接口中只能有一个方法

 

4.使用的原因:减少冗余

4.1)冗余代码一:

public class Demo05 {    public static void main(String[] args) {

        Thread t = new Thread(new MyRunnable());
t.start();
}
static class MyRunnable implements Runnable{
@Override
public void run() {
System.out.println("谁知盘中餐");
}
}
}

4.2)冗余代码二:
public class Demo05 {
public static void main(String[] args) {

new Thread(new Runnable() {
@Override
public void run() {
System.out.println("锄禾日当午");
}
}).start();
}
}
采用Lamdba表达式:很简洁
public class Demo05 {
public static void main(String[] args) {
new Thread(() -> System.out.println("锄禾日当午")).start();
}
}


5.代码实例:

 1 public class Demo05 {
 2     public static void main(String[] args) {
 3         //面向对象思想
 4 //        print(new Main() {
 5 //            @Override
 6 //            public int sum(int x, int y) {
 7 //                return x+y;
 8 //            }
 9 //        },100,200);
10         //  }
11         
12         //Lambda表达式
13         print((int x,int y) ->{return x+y;},100,200);
14         
15     }
16     
17     public static void print(Main m,int x,int y){
18         int sum = m.sum(x, y);
19         System.out.println(sum);
20     }
21     static interface Main{
22         int sum(int x,int y);
23     }
24 }

                                                    结语

                                又学完了一个核心类库了,加油。

 

标签:类库,Java,Thread,void,run,线程,new,public
来源: https://www.cnblogs.com/baiyangshu/p/14901242.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有