JavaSE-09 Thread 多线程

147 篇文章 1 订阅
147 篇文章 2 订阅

原文链接:
https://blog.51cto.com/u_15316078/5324143

1. 线程简介

1.1 普通方法可以调用很多线程

1.2 程序、进程、线程

  • 程序跑起来变成进程,进程里面分为若干个线程 :例如main函数就是主线程(是系统入口,用于执行多个程序),gc垃圾回收机制也是一个线程
  • 多线程是模拟出来的,真正的多线程是指很多cpu,即多核,但是因为cpu执行代码切换得很快,所以有同时执行的感觉
  • 多个线程是由调度器安排调度与操作系统相关的,控制到cpu先后顺序
  • 对同一个资源操作时,会发生资源抢夺的问题,需要加入并发控制

2. 线程创建:com.fenfen.Thread.Demo1

2.1继承Thread类

三步走:

1.自定义线程类继承Thread类

2.重写run()方法,编写线程执行力

3.创建线程对象,调用start()方法启动线程

public class TestTread1 extends Thread{
@Override
public void run() {
//run 方法线程体
for (int i = 0; i < 20; i++) {
System.out.println("我在通宵肝代码---"+i);
}
}
public static void main(String[] args) {
//main方法,主线程
//创建一个线程对象,并调用start方法
TestTread1 testTread1 = new TestTread1();
testTread1.start();
//如果是run方法就是正常的先跑run方法上面的
testTread1.run();
for (int i = 0; i < 200; i++) {
System.out.println("我在学习多线程---"+i);
}
/*
输出结果是交替执行的,由cpu调度执行
*/
}

2.2 用集成thread实现网图下载的多线程

1.学完io流后记得补代码

2.3 实现runnable接口

三步走:

1.定义MyRunnable类实现Runnable接口

2.实现run()方法,编写线程执行体

3.创建线程对象,传入目标对象+调用start()方法启动线程

public class TestThread3 implements Runnable{
@Override
public void run() {
//run 方法线程体
for (int i = 0; i < 20; i++) {
System.out.println("我在通宵肝代码---"+i);
}
}
public static void main(String[] args) {
//main方法,主线程
//创建Runnable接口实现类对象,并调用start方法
TestThread3 testTread3 = new TestThread3();
//创建线程对象,通过线程对象来开启我们的线程,代理
Thread thread = new Thread(testTread3);
thread.start();
//new Thread(testTread3).start();或者直接说一句这个
for (int i = 0; i < 200; i++) {
System.out.println("我在学习多线程---"+i);
}
/*

1、去看源码发现,本质是因为:Thread也实现了Runnable接口,Runnable就一个run方法在里面

2、继承是单继承,推荐使用Runnable方法

*/
}
}

2.4 初始并发问题

多个线程操作同一个资源的情况下,并发出现问题,线程不安全了,数据紊乱

public class TestThread4 implements Runnable{
//票数
private int ticketnums = 10;
@Override
public void run() {
while (true){
if (ticketnums<=0){
break;
}
//模拟延迟sleep
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();
}
}

2.5 利用多线程实现龟兔赛跑

思路:

1.fori循环

2.方法用boolean写一个判断是否完成比赛,传递i过去

3.比赛结束跳出循环

4.新建两个线程调用

5.让兔子线程休息,记得try和catch一下

public class Race implements Runnable{
//胜利者
private static String winner;
@Override
public void run() {
for (int i = 0; i <= 100; i++) {
//模拟兔子休息sleep
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;
}{
if (steps >=100){
winner = Thread.currentThread().getName();
System.out.println("winner is "+ winner);
return true;
}
}
return false;
}
public static void main(String[] args) {
Race race = new Race();
new Thread(race,"兔子").start();
new Thread(race,"乌龟").start();
}
}

2.6 实现Callable接口

好几步走:

1.实现Callable接口,需要返回值类型

2.重写call方法,需要抛出异常

3.创建目标对象

4.创建执行服务

5.提交执行

6.获取结果

7.关闭服务

了解就好,如果以后用到再学,再来补,先割一下

2.7 静态代理模式

思路:

1.两个类都改写接口的方法

2.将真实对象通过参数传进去(构造器),代理对象从而代理真实角色

好处:

代理对象可以做很多真实对象做不了的事情,真实对象专注做自己的事情

就是线程的底部原理

public class StaticProxy {
public static void main(String[] args) {
You you = new You();
//这边用lambda表达式表示:Thread代理一个真实的Runnable接口,并且调用了start方法
new Thread(()-> System.out.println("我爱你")).start();
//或者精简成new WeddingCompany(new You()).HappyMarry();
WeddingCompany weddingCompany = new WeddingCompany(new You());
weddingCompany.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 after() {
System.out.println("结婚之后,收尾款");
}
private void before() {
System.out.println("结婚之前,布置现场");
}
}

2.8 Lambda表达式

2.8.1 基本内容

Lambda表达式属于函数式编程

例如:a->System.out.println(“我在学习多线程->”+i);

函数式接口的定义:任何接口只包含了一个抽象方法,那就是函数式接口,就可以通过lambda表达式来创建该接口的对象

2.8.2 简略代码的方法

静态内部类

public class TestLambda2 {
//利用静态内部类的方式:加上static
static class Like11 implements ILike1{
@Override
public void lambda() {
System.out.println("i like lambda1");
}
}
public static void main(String[] args) {
Like11 like11 = new Like11();
like11.lambda();
}
}
//1、定义一个函数式接口
interface ILike1 {
void lambda();
}

局部内部类

public class TestLambda3 {
public static void main(String[] args) {
class Like3 implements ILike3{
@Override
public void lambda() {
System.out.println("i like lambda3");
}
}
Like3 like3 = new Like3();
like3.lambda();
}
}
//1、定义一个函数式接口
interface ILike3 {
void lambda();
}

匿名内部类:没有类似的名称

public class TestLambda4 {
public static void main(String[] args) {
ILike4 like4 = new ILike4(){
@Override
public void lambda() {
System.out.println("i like lambda4");
}
};
like4.lambda();
}
}
//1、定义一个函数式接口
interface ILike4 {
void lambda();
}

用lambda简化

public class TestLambda5 {
public static void main(String[] args) {
ILike5 like5= ()->{
System.out.println("i like lambda5");
};
like5.lambda();
}
}
//1、定义一个函数式接口
interface ILike5 {
void lambda();
}

再写一个

正常接口代码2

public class TestLambda6 {
public static void main(String[] args) {
Love love = new Love();
love.love(666);
}
}
interface Ilove{
void love(int a );
}
class Love implements Ilove{
@Override
public void love(int a) {
System.out.println("i love life-->"+a);
}
}

匿名内部类2

public class TestLambda7 {
public static void main(String[] args) {
Ilove1 ilove1 = new Ilove1(){//记得改成接口的类
@Override
public void love(int a) {
System.out.println("i love life-->"+a);
}
};
ilove1.love(888);
}
}
interface Ilove1{
void love(int a );
}

7.用lambda简化2

public static void main(String[] args) {
Ilove2 ilove2 = (int a)-> {
System.out.println("i love life-->"+a);
};
//再简化:①去掉参数类型
ilove2 = (a)-> {
System.out.println("i love life-->"+a);
};
//再简化:把括号都简化没了
ilove2 = a->{
System.out.println("i love life-->"+a);
};
ilove2.love(888);
}
}
interface Ilove2{
void love(int a );
}

用lambda简化多个参数

登录后复制

public class TestLambda9 {
public static void main(String[] args) {
Ilove3 ilove3 = null;
ilove3 = (a,b)-> {
System.out.println("i love you-->"+a+" "+b);
};
ilove3.love(520,1314);
/*
多个参数也可以去掉参数类型,要去掉就全部去掉,并且带上括号
*/
}
}
interface Ilove3{
void love(int a,int b );
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值