线程的创建方式
继承Thread类(Thread类就是线程类,继承后自然就是线程类了)
写一个类,实现 Runnable 接口,然后创建一个线程对象,将实现类对象放到线程对象中(Runnable的实现类是线程运行时执行时所需要的,并不是线程对象)
-
实现 Callable 接口,Callable 与 Runnable 类似 ,但是有返回值。
public interface Ca 11able<V> { V call() throws Exception; }
通过线程池( Executor )启动多线程
讲解线程创建和基本使用的时候,我们
代理设计模式
在现实中,代理几乎无处不在。比如代理商代替厂商卖商品;外卖小哥代你买东西并送到手;你下楼买东西,你妈妈让你顺便把垃圾扔下去..... ;
以送外卖为例子来举个例子,整个过程中的核心是配送 。这就引出几个元素:
- 代理人:外卖小哥
- 被代理人:买外卖的人,比如你
- 要做的事情(行为):点外卖后,将东西送到被代理人这里
我们首先定义一个接口,接口里有一个配送方法
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 类,是因为默认的行为在控制台中没有任何的输出 ,看不出来什么。
方法:
线程创建:new Thread()
线程启动:start()
线程运行:run()
直接继承Thread
步骤:
创建类继承 Thread
重写父类run方法
创建对象,调用 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>