多线程

线程的创建方式

  1. 继承Thread类(Thread类就是线程类,继承后自然就是线程类了)

  2. 写一个类,实现 Runnable 接口,然后创建一个线程对象,将实现类对象放到线程对象中(Runnable的实现类是线程运行时执行时所需要的,并不是线程对象)

  3. 实现 Callable 接口,Callable 与 Runnable 类似 ,但是有返回值。

    public interface Ca 11able<V> {
     V call() throws Exception;
    }
    
  4. 通过线程池( Executor )启动多线程

讲解线程创建和基本使用的时候,我们

代理设计模式

在现实中,代理几乎无处不在。比如代理商代替厂商卖商品;外卖小哥代你买东西并送到手;你下楼买东西,你妈妈让你顺便把垃圾扔下去..... ;

以送外卖为例子来举个例子,整个过程中的核心是配送 。这就引出几个元素:

  1. 代理人:外卖小哥
  2. 被代理人:买外卖的人,比如你
  3. 要做的事情(行为):点外卖后,将东西送到被代理人这里

我们首先定义一个接口,接口里有一个配送方法

public interface FoodDelivered {
    /**配送*/
    void send();
}

代码中有个send()方法,该方 法是用来实现配送功能的,按照以前的方式,配送服务需要商家来自己来配送,所以我们定义一个商家类,该商家类实现FoodDelivered接口

public class Restaurant implements FoodDelivered {

    @Override
    public void send() {
        System.out.println("派送食物");
    }
}

商家类实现FoodDelivered接口,并实现了send方法进行配送食品。再写一个测试类来测试一下上述代码

public static void main(String[] args) {
    Restaurant r = new Restaurant();
    r.send();   // 派送食物
}

测试方法里创建了一个商家对象,并调用send方法来进行配送服务,可以看到控制台里打印了派送食品,这里表示商家进行了配送服务 。

现在我们有了外卖平台,商家就可以把派送服务委托给外卖小哥来完成,外卖小哥便成了代理者,因为我们的小哥也是进行配送服务的,所以我们再定义一个外卖小哥的类,并实现 FoodDelivered 接口

public class Deliveryman implements FoodDelivered {

    private Restaurant restaurant;

    public Deliveryman(Restaurant restaurant) {
        this.restaurant = restaurant;
    }

    @Override
    public void send() {
        System.out.println("外卖小哥派送");
        this.restaurant.send();
    }
}

这里我们注意一下,Deliveryman类里有个成员是Restaurant类型的,这个类型是商家的类型,就是我们的委托人 (注:这里构造方法的参数是Restaurant类型,也就是说我们的委托人可以是Restaurant类及其子类,这样灵活性很差。这个参数可以换成FoodDelivered类型,这样只要实现了FoodDelivered接口的所有类都可以作为委托人,灵活性会提高)

构造方法里会传一个Restaurant对象过来,已完成对成员restaurant的初始化。然后在send方法里调用委托人的send方法,并在前边打印一句“外卖小哥派送”

public static void main(String[] args) {
    Restaurant restaurant = new Restaurant();
    Deliveryman deliveryman = new Deliveryman(restaurant);
    deliveryman.send();
}

输出的结果

外卖小哥派送
派送食物

这里可以我们首先创建一个商家对象,然后创建一个外卖小哥对象,并把商家对象作为参数传递给外卖小哥对象,最后我们调用外卖小哥的send方法,而不是商家的send方法,这样就把配送的服务委托给了外卖小哥来完成。

以上方式我们称之为静态代理,静态代理是在代码编译期前进行的,代码编译后就无法再改变了。 线程的前两种应用就是使用了这种设计模式

线程的创建和调用

这里使用自定义类继承 Thread 来进行演示。之所以没有直接使用 Thread 类,是因为默认的行为在控制台中没有任何的输出 ,看不出来什么。

方法:

  1. 线程创建:new Thread()

  2. 线程启动:start()

  3. 线程运行:run()

直接继承Thread

步骤:

  1. 创建类继承 Thread

  2. 重写父类run方法

  3. 创建对象,调用 start 方法进入就绪状态

<pre class="md-fences md-end-block ty-contain-cm modeLoaded" spellcheck="false" lang="java" cid="n105" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: var(--monospace); font-size: 0.9em; display: block; break-inside: avoid; text-align: left; white-space: normal; background-image: inherit; background-position: inherit; background-size: inherit; background-repeat: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: rgb(248, 248, 248); position: relative !important; border: 1px solid rgb(231, 234, 237); border-radius: 3px; padding: 8px 4px 6px; margin-bottom: 15px; margin-top: 15px; width: inherit; color: rgb(51, 51, 51); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;">public class MyThread extends Thread{
 //  线程运行是调用 run 方法,这要看什么时候线程会被调用
 @Override
 public void run() {
 System.out.println("我是一个线程");
 }
}</pre>

测试

<pre class="md-fences md-end-block ty-contain-cm modeLoaded" spellcheck="false" lang="java" cid="n107" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: var(--monospace); font-size: 0.9em; display: block; break-inside: avoid; text-align: left; white-space: normal; background-image: inherit; background-position: inherit; background-size: inherit; background-repeat: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: rgb(248, 248, 248); position: relative !important; border: 1px solid rgb(231, 234, 237); border-radius: 3px; padding: 8px 4px 6px; margin-bottom: 15px; margin-top: 15px; width: inherit; color: rgb(51, 51, 51); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;">public class Test {

 public static void main(String[] args) {

 MyThread thread = new MyThread();

 //  线程启动是调用 start 方法,让线程进入到就绪状态
 thread.start();
 }
}</pre>

结果

<pre class="md-fences md-end-block ty-contain-cm modeLoaded" spellcheck="false" lang="" cid="n109" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: var(--monospace); font-size: 0.9em; display: block; break-inside: avoid; text-align: left; white-space: normal; background-image: inherit; background-position: inherit; background-size: inherit; background-repeat: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: rgb(248, 248, 248); position: relative !important; border: 1px solid rgb(231, 234, 237); border-radius: 3px; padding: 8px 4px 6px; margin-bottom: 15px; margin-top: 15px; width: inherit; color: rgb(51, 51, 51); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;">我是一个线程</pre>

实现 Runnable 接口

步骤:

1.新建类,实现 Runnable 接口中的 run 方法

2.创建线程对象,将Runnable 实现类对象放到线程的构造器中

3.调用线程对象的 start 方法

实现接口

<pre class="md-fences md-end-block ty-contain-cm modeLoaded" spellcheck="false" lang="java" cid="n118" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: var(--monospace); font-size: 0.9em; display: block; break-inside: avoid; text-align: left; white-space: normal; background-image: inherit; background-position: inherit; background-size: inherit; background-repeat: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: rgb(248, 248, 248); position: relative !important; border: 1px solid rgb(231, 234, 237); border-radius: 3px; padding: 8px 4px 6px; margin-bottom: 15px; margin-top: 15px; width: inherit; color: rgb(51, 51, 51); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;">/**
 *  注意:实现 Runnable接口只是对run方法进行了实现。
 *  在线程对象中可以调用这个方法。
 * @author 喵先生
 */
public class MyRunnable implements Runnable{

 @Override
 public void run() {
 System.out.println("我是一个线程运行的主体.....");
 }
}</pre>

测试

<pre class="md-fences md-end-block ty-contain-cm modeLoaded" spellcheck="false" lang="java" cid="n120" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: var(--monospace); font-size: 0.9em; display: block; break-inside: avoid; text-align: left; white-space: normal; background-image: inherit; background-position: inherit; background-size: inherit; background-repeat: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: rgb(248, 248, 248); position: relative !important; border: 1px solid rgb(231, 234, 237); border-radius: 3px; padding: 8px 4px 6px; margin-bottom: 15px; margin-top: 15px; width: inherit; color: rgb(51, 51, 51); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;">public class Test {

 public static void main(String[] args) {

 MyRunnable runnable = new MyRunnable();
 new Thread(runnable).start();
 }
}</pre>

输出的结果

<pre class="md-fences md-end-block ty-contain-cm modeLoaded" spellcheck="false" lang="" cid="n122" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: var(--monospace); font-size: 0.9em; display: block; break-inside: avoid; text-align: left; white-space: normal; background-image: inherit; background-position: inherit; background-size: inherit; background-repeat: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: rgb(248, 248, 248); position: relative !important; border: 1px solid rgb(231, 234, 237); border-radius: 3px; padding: 8px 4px 6px; margin-bottom: 15px; margin-top: 15px; width: inherit; color: rgb(51, 51, 51); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;">我是一个线程运行的主体.....</pre>
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容