程序:程序是数据和指令的有序集合。
进程:进程是系统资源分配的最小单位
线程:线程是资源调度和程序执行的最小单位
(一个进程中至少有一个线程)
1.线程的创建方式
1.1.继承Thread类
public class TestThread extends Thread {
public TestThread() {
}
public TestThread(String name) {
super(name);
}
@Override
public void run() {
for (int i = 0; i < 100; i++) {
System.out.println(Thread.currentThread().getName() + "-->" + i);
}
}
public static void main(String[] args) {
TestThread thread0 = new TestThread("小李");
TestThread thread1 = new TestThread("小王");
TestThread thread2 = new TestThread();
thread0.start();
thread1.start();
thread2.start();
for (int i = 0; i < 100; i++) {
System.out.println(Thread.currentThread().getName() + "-->" + i);
}
}
}
1.2.实现Runnable接口
public class TestThread2 implements Runnable {
@Override
public void run() {
for (int i = 0; i < 100; i++) {
System.out.println(Thread.currentThread().getName() + "-->" + i);
}
}
public static void main(String[] args) {
TestThread2 thread2 = new TestThread2();
new Thread(thread2,"小王").start();
new Thread(thread2,"小李").start();
new Thread(thread2).start();
for (int i = 0; i < 100; i++) {
System.out.println(Thread.currentThread().getName() + "-->" + i);
}
}
}
1.3.实现Callable接口
class TestThread3 implements Callable<Boolean>{
@Override
public Boolean call() throws Exception {
for (int i = 0; i < 100; i++) {
System.out.println(Thread.currentThread().getName() + "-->" + i);
}
return true;
}
public static void main(String[] args) throws Exception {
TestThread3 thread3 = new TestThread3();//默认名字pool-1-thread-1
TestThread3 thread31 = new TestThread3();//pool-1-thread-2
TestThread3 thread32 = new TestThread3();//pool-1-thread-3
//创建执行服务
ExecutorService service = Executors.newFixedThreadPool(3);
//提交执行
Future<Boolean> submit = service.submit(thread3);
Future<Boolean> submit1 = service.submit(thread31);
Future<Boolean> submit2 = service.submit(thread32);
//获取执行结果
Boolean sr = submit.get();
Boolean sr1 = submit1.get();
Boolean sr2 = submit2.get();
System.out.println(sr);
System.out.println(sr1);
System.out.println(sr2);
//关闭执行服务
service.shutdownNow();
for (int i = 0; i < 100; i++) {
System.out.println(Thread.currentThread().getName() + "-->" + i);
}
}
}
1.4.总结
- 对于
Thread.currentThread().getName()
分析
创建方式 | 说明 |
继承Thread类 | 默认名称是Thread-0,Thread-1…。可以通过继承过来的构造方法,给线程起别名 |
实现Runnable接口 | 默认名称是Thread-0,Thread-1…。可以通过Thread的构造方法,给线程起别名 |
实现Callable接口 | 默认名称是pool-1-thread-1,pool-1-thread-2…。起别名方法未知。 |
匿名内部类方式(Lambda) | 默认名称是Thread-0,Thread-1…。可以通过Thread的构造方法,给线程起别名 |
线程不安全
的理解
理解:多个线程操作同一资源的情况下,线程不安全,数据出现紊乱。
重点:
开启一个线程并不会立即执行,而是通过CPU调度执行。
2.Lambda的引入
要了解Lambda表达式先得知道函数式接口的定义。
函数式接口:
- 任何接口,如果只包含唯一一个抽象方法,那么它就是一个函数式接口。
- 对于函数式接口,我们可以通过Lambda表达式来创建该接口的对象。
例子:比如Runnable接口就是一个函数式接口。
2.1.简介
lambda表达式作为java8的新特性,面向函数式编程,使代码更加简洁,同时也提高了编程效率。
2.2.格式
lambda使用的规则大致为:
( 参 数 ) −> { 代 码 主 体 }
注意:左边括号不是必须的,当只有一个参数时可以省略;右侧大括号也不是必须的,如果只有一行代码,可以省略。
2.3.使用(创建线程为例)
//创建了一个名字叫"哈哈"的线程并开启
new Thread(()->{
代码主体
},"哈哈").start();
2.4.总结
Lambda直观的作用
:我们不用再去声明一个函数式接口的实现类了。
3.静态代理
/*
静态代理:
目标对象和代理对象都实现同一个行为接口。
代理对象要代理目标对象。
*/
public class StaticProxy {
public static void main(String[] args) {
//Thread相当于代理对象,Runnable相当于目标对象
new Thread(() -> {
for (int i = 0; i < 10; i++) {
System.out.println(i);
}
}, "哈哈").start();
//WeddingCompany相当于代理对象,You相当于目标对象
new WeddingCompany(new You()).HappyMarry();
}
}
//行为接口
interface Marry {
void HappyMarry();
}
//目标对象
class You implements Marry {
@Override
public void HappyMarry() {
System.out.println("我要结婚了");
}
}
//代理对象
class WeddingCompany implements Marry {
private Marry target;
public WeddingCompany(Marry target) {
this.target = target;
}
@Override
public void HappyMarry() {
before();
this.target.HappyMarry();
after();
}
private void before() {
System.out.println("婚前,布置婚礼现场");
}
private void after() {
System.out.println("婚后,收款");
}
}