java中的多线程

实现

方法一:继承Thread类

package com;

public class demo1 {
    public static void main(String[] args) {
        MyThread myThread = new MyThread("a");   // 创建线程对象
        myThread.start();  // 启动线程
    }
}


class MyThread extends Thread{
    public MyThread(String name) {
        super(name);
    }

    @Override
    public void run() {
        System.out.println("线程" + Thread.currentThread().getName());    // 获得当前线程的线程名
    }
}
结果:
线程a
  • 步骤,继承Thread类,重写run()方法,创建线程对象,调用start()启动线程
  • 此例中涉及到的Thread中方法:
    • start() 启动线程,将线程放入就绪队列等待操作系统调度,注意不是立即执行,调度后执行run()方法
    • run() 需要子类重写
    • currentThread() 返回对当前正在执行的线程对象的引用
    • getName() 返回此线程的名称
  • main()方法也是一个线程,叫主线程

方法二:实现Runnable接口

package com;

public class demo2 {
    public static void main(String[] args) {
        MyRun myRun = new MyRun();  // 创建目标对象

        Thread thread = new Thread(myRun, "a");  // 创建线程对象
        thread.start();  // 开启线程

//        new Thread(myRun, "a").start();
    }
}


class MyRun implements Runnable{
    @Override
    public void run() {
        System.out.println("线程" + Thread.currentThread().getName());
    }
}
  • 实现Rubbable接口,重写run()方法,创建目标对象,创建线程对象,调用start()启动线程

  • MyRun类的对象不是线程对象

  • Thread类实现了Runnable接口

状态

  • 生命周期:

在这里插入图片描述

  • 在Thread.State类中定义了6中状态:

  • NEW
    尚未启动的线程处于此状态。
    RUNNABLE
    在Java虚拟机中执行的线程处于此状态。
    BLOCKED
    被阻塞等待监视器锁定的线程处于此状态。
    WAITING
    正在等待另一个线程执行特定动作的线程处于此状态。
    TIMED_WAITING
    正在等待另一个线程执行动作达到指定等待时间的线程处于此状态。
    TERMINATED
    已退出的线程处于此状态。

  • 方法:getState() 返回此线程的状态

多线程的效果

package com;

public class demo2 {
    public static void main(String[] args) {
        MyRun myRun = new MyRun();  // 创建目标对象

        new Thread(myRun, "a").start();  // 创建线程对象
        new Thread(myRun, "b").start();  // 创建线程对象
        
    }
}

class MyRun implements Runnable{
    @Override
    public void run() {
        for (int i = 0; i < 1000; i++) {
            System.out.println("线程" + Thread.currentThread().getName());
        }
    }
}

一部分结果:
线程a
线程a
线程b
线程b
线程b
线程b
线程b
线程b
线程b
线程a
线程a
线程a

优先级

共有10个优先级
下面是定义好的三个常量

/**
  * The minimum priority that a thread can have.
  */
 public final static int MIN_PRIORITY = 1;

/**
  * The default priority that is assigned to a thread.
  */
 public final static int NORM_PRIORITY = 5;

 /**
  * The maximum priority that a thread can have.
  */
 public final static int MAX_PRIORITY = 10;
  • 优先级高的不一定先执行

  • 方法:
    getPriority() 返回此线程的优先级
    setPriority(int newPriority) 更改此线程的优先级

其他方法

  • sleep() 使当前正在执行的线程以指定的时间睡眠
package com.demo2;

public class TestSleep {

    public static void main(String[] args) {
        MySleep m1 = new MySleep();

        new Thread(m1).start();
    }

}


class MySleep implements Runnable {

    @Override
    public void run() {
        for (int i = 0; i < 10; i++) {
            System.out.println(i);
            try {
                Thread.sleep(1000);   //  sleep
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}
  • yield() 当前线程进入就绪状态,与其他线程重新竞争资源,注意,不是说让给其他线程自己就不参与竞争了
  • join() 等待这个线程死亡 (效果看例子)
package com.demo2;

public class TestJoin extends Thread{

    @Override
    public void run() {
        for (int i = 0; i < 2000; i++) {
            System.out.println("插队" + Thread.currentThread().getName());
        }
    }

    public static void main(String[] args) throws InterruptedException {
        TestJoin testJoin = new TestJoin();
        testJoin.start();

        for (int i = 0; i < 500; i++) {
            if(i == 200){
                testJoin.join();   // join
            }
            System.out.println("main"+ i);
        }
    }
}
/*
这有main线程和testJoin两个线程
当main执行到i==200时要等testJoin线程执行完再继续执行

结果:
.
.
main193
插队Thread-0
插队Thread-0
插队Thread-0
main194
main195
插队Thread-0
main196
main197
main198
main199   从这开始,main要等Thread-0执行完再继续执行
插队Thread-0  
插队Thread-0
插队Thread-0
插队Thread-0  省略部分全是Thread-0
.
.
.
插队Thread-0
插队Thread-0
插队Thread-0
插队Thread-0
main200
main201
main202
main203
main204
main205 后面全是main了
.
main499

 */
  • 等等

同步

使用synchronized声明临界区

wait()方法,让无法进行数据存取的线程暂时进入休眠状态

notify(),唤醒处于休眠状态的线程,通常由线程对象调用

notifyall(),一次唤醒所有

  • 下例中,需求:只有用户将money存入账户后银行才能扣款
class Account{
    private int Credit;
    private boolean available = false;

    // 存款方法
    public synchronized void put(int money){
        //当get()未执行时,等待get()方法执行
        while (available == true){
            try {
                wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        Credit = money;
        // 告知get()方法款项已存入,可执行扣款操作
        available = true;
        notifyAll();
    }

    // 扣款方法
    public synchronized int get(){
        //当put()未执行时,等待put()方法执行
        while (available == false){
            try {
                wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        // 告知put()方法应缴款项已扣除,可以执行存款操作
        available = false;
        notifyAll();
        return Credit;
    }
}

其他

1、Timer和TimerTask

package com;

import java.util.Timer;
import java.util.TimerTask;

public class demo1 {

    public static void main(String[] args) {

        MyTask myTask = new MyTask();
        Timer timer = new Timer();
        timer.schedule(myTask, 10, 10);   // 前面任务延迟,后面跟着延迟
        timer.scheduleAtFixedRate(myTask, 10 ,10);  // 无论上一次任务是否结束,间隔一到立即执行
        
    }
}

class MyTask extends TimerTask{
    @Override
    public void run() {
        System.out.println("yahou");
    }
}

2、Callable接口:

https://www.jb51.net/article/145487.htm

https://blog.youkuaiyun.com/niuzhucedenglu/article/details/80525432

本文参考源码、jdk api文档、《java从入门到精通》明日学院 编著、《java程序设计与计算思维》 赵军 吴灿铭编著

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

臭屁虾

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值