多线程学习

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档


前言

本文用自己最通俗的语言解释整理多线程的知识点,请指教


一、什么是多线程?

线程就像是人边看电视,边吃饭,可以同时做多件事,或者说是做多件事之间的时间间隙很短,几乎忽略。放在程序里面,就是完成多件线程。首先要知道不是所有程序语言都支持线程,有些语言只能运行完成一件任务后再进行下一项目的开发,Java提供了线程的并发(多个线程访问同一对象)执行。得区分开和进程的差别,进程是计算机系统的多任务操作系统的单位,是正在执行的程序,也可以多段进程先后执行,而一个进程就具有多个可以并发执行的线程。

二、实现多线程的两种常用方式

1.继承Thread类

代码如下(示例):

package com.java;

public class Solution3 {
    public static void main(String[] args) {
        System.out.println("main线程执行了");
        new MyThread().start();
    }
}
class MyThread extends Thread{
    @Override
    public void run() {
        System.out.println("MyThread线程执行了");
    }
}

重写run()方法,通过start()方法启动线程 

2.实现Runnable接口

代码如下(示例):

package com.java;

public class Solution3 {
    public static void main(String[] args) {
        System.out.println("main线程执行了");
        TestThread1 testThread1 = new TestThread1();
        new Thread(testThread1).start();
     
    }
}
class TestThread1 implements Runnable{
    @Override
    public void run() {
        System.out.println("1");
    }

}

实质上也是Thread类实现了Runnable,前者中的run方法正是对后者run方法的具体实现,同时,因为Java不支持多继承,为满足需求,常使用实现Runnable接口来使类具有使用线程的的功能。

三、线程的生命周期

线程具有生命周期,其中包含7种状态:

1.出生状态:线程被创建时处于的状态,在调用start()方法前都属于这一状态;

2.就绪状态:调用start后就进这一状态,然后会在就绪与运行状态下转换,同时能进入其他状态;

3.运行状态:得到系统分配的资源后就进入这一状态;

4.等待状态:调用wait方法后,此时不占用系统资源,用notify或notifyAll方法唤醒;

5.休眠状态:调用sleep方法后,占用系统资源;

6.阻塞状态:在运行状态下发出输入/输出请求后会进入阻塞状态;

7.死亡状态:run方法执行完毕后进入死亡状态。

调用Thread.State方法可查看所处状态:

四、操作线程的常用方法

1.线程的休眠

Thread.sleep(1000); //这代表休眠2秒,参数单位是毫秒

它的执行可能会抛出InterruptedException,所以要将它放在try-catch块中

常用来放大线程运行的错误。

小扩展:10秒倒计时

package com.java.practice;

public class Demo001 {
    public static void main(String[] args) throws InterruptedException {
    tenDown();
    }

    public static void tenDown() throws InterruptedException {
        int nums = 10;
        while(true){
            Thread.sleep(1000);
            System.out.println(nums--);
            if(nums == 0){
                break;
            }
        }
    }
}

2.线程的加入

Thread.join() 当使用某个线程加入到另一个线程中后,另一个线程会等待该线程执行完毕后再继续执行。就像在打游戏的时候,女朋友打电话进来,必须先接完电话再打游戏!

3.线程的中断

不建议使用JDK中的stop方法,会导致阻塞。

建议利用布尔型标记自定义stop方法,像这样:

private boolean flag = true;

@Override
public void run() {
    int i = 0;
    while(flag){
        System.out.println("run thread 跑了"+i++);
    }
}

public void stop() {
    this.flag = false;

}

 4.线程的礼让

Thread.yield()提醒具有同样优先级的线程可以将资源让出去,但是不一定让得出去,就像100米短跑,我让你先跑,但是你还是不一定能跑得过我,最后谁先冲线(执行完毕)不一定。

五、线程的优先级

字面意思也好理解,这里是把线程的优先级分为1-10级,下面是Thread类中的成员变量:

    • static intMAX_PRIORITY

      线程可以拥有的最大优先级。(10)

      static intMIN_PRIORITY

      线程可以拥有的最低优先级。(1)

      static intNORM_PRIORITY

      分配给线程的默认优先级。(5)也可以自定义

    • voidsetPriority​(int newPriority)

      更改此线程的优先级。

六、线程的同步

为啥要同步?因为线程不安全,就像两个人买电影票,但只剩下1张了,两个人同时去买,最后应该是一人能买到,一人不能买到,线程如果不同步,余票会不会变成-1张。

Java提供了同步机制,可以有效防止资源冲突,使用synchronized关键字

首先是同步块,synchronized(Object){}

package com.java.practice;

public class UnsafeBank {
    public static void main(String[] args) {
        Account account = new Account(100,"结婚基金");

        Drawing you = new Drawing(account,50,"you");
        Drawing girl = new Drawing(account,100,"girl");
        you.start();
        girl.start();
    }

}
//账户
 class Account{
    int money;
    String name;
    public  Account(int money,String name){
        this.money = money;
        this.name = name;
    }
}
class Drawing extends Thread{
    Account account;
    int drawingMoney;
    int nowMoney;

    @Override
    public void run() {
        //锁的是增删改的对象,也就是银行账户;同步块
        synchronized (account) {
            //判断钱够不够
            if (drawingMoney > account.money) {
                System.out.println(this.getName() + "钱不够,取不了");
                return;
            }

            account.money = account.money - drawingMoney;
            nowMoney = nowMoney + drawingMoney;   //更新

            System.out.println(account.name + "余额为:" + account.money);
            System.out.println(this.getName() + "手里的钱:" + nowMoney);
        }
    }

    public Drawing(Account account, int drawingMoney,String name){
        super(name);
        this.account = account;
        this.drawingMoney =drawingMoney;

    }

}

还有同步方法,即在方法前加关键字:

synchronized void f(){}

持续更新中......


  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值