Java-多线程笔记

1、创建多线程的三种方式

  • 继承Thread
  • 实现Runnable接口

1、通过继承Thread类来创建并启动多线程的一般步骤如下:

1)定义Thread类的子类,并重写该类的run()方法,该方法的方法体就是线程需要完成的任务,run()方法也称为线程执行体。

2)创建Thread子类的实例,也就是创建了线程对象

3)启动线程,即调用线程的start()方法

代码实例:

 public calss MyThread extends Thread{ //继承Thread类
     public void run(){
         //重写run()方法
         //实现业务逻辑
     }
 }
复制代码

main方法调用:

    public calss Main{
        public static void main(String[] args){
            MyThread mt = new MyThread();   //创建线程对象
            mt.start();  //启动线程
        }
    }
复制代码

2、通过实现Runnable接口创建并启动线程一般步骤如下:

1)定义Runnable接口的实现类,一样要重写run()方法,这个run()方法和Thread中的run()方法一样是线程的执行体

2)创建Runnable实现类的实例,并用这个实例作为Thread的target来创建Thread对象,这个Thread对象才是真正的线程对象

3)第三步依然是通过调用线程对象的start()方法来启动线程

代码实例:

public calss MyThread implements Runnable{
    public void run(){
        //重写run()方法
        //实现业务逻辑
    }
}
复制代码
public calss Main{
    public static void main(String[] args){
        MyThread my = new MyThread();
        Thread thread = new Thread(my);
        thread().start();//或者 new Thread(new MyThread()).start();
    }
}
复制代码

2、一些常用方法

1 currentThread()

返回对当前正在执行的线程对象的引用。

2 getId()

返回此线程的标识符

3 getName()

返回此线程的名称

4 getPriority()

返回此线程的优先级

5 isAlive()

测试这个线程是否还处于活动状态。

什么是活动状态呢?

活动状态就是线程已经启动且尚未终止。线程处于正在运行或准备运行的状态。

6 sleep(long millis)

使当前正在执行的线程以指定的毫秒数“休眠”(暂时停止执行),具体取决于系统定时器和调度程序的精度和准确性。

7 interrupt()

中断这个线程。

8 interrupted() 和isInterrupted()

interrupted():测试当前线程是否已经是中断状态,执行后具有将状态标志清除为false的功能

isInterrupted(): 测试线程Thread对相关是否已经是中断状态,但部清楚状态标志

9 setName(String name)

将此线程的名称更改为等于参数 name 。

10 isDaemon()

测试这个线程是否是守护线程。

11 setDaemon(boolean on)

将此线程标记为 daemon线程或用户线程。

12 join()

在很多情况下,主线程生成并起动了子线程,如果子线程里要进行大量的耗时的运算,主线程往往将于子线程之前结束,但是如果主线程处理完其他的事务后,需要用到子线程的处理结果,也就是主线程需要等待子线程执行完成之后再结束,这个时候就要用到join()方法了。

join()的作用是:“等待该线程终止”,这里需要理解的就是该线程是指的主线程等待子线程的终止。也就是在子线程调用了join()方法后面的代码,只有等到子线程结束了才能执行

13 yield()

yield()方法的作用是放弃当前的CPU资源,将它让给其他的任务去占用CPU时间。注意:放弃的时间不确定,可能一会就会重新获得CPU时间片。

14 setPriority(int newPriority)

更改此线程的优先级

3、线程同步问题

  1. 在需要同步的方法的方法签名中加入synchronized关键字。

    public synchronized void accessVal(int newVal);

    synchronized 方法控制对“对象的类成员变量”的访问:每个对象对应一把锁,每个 synchronized 方法都必须获得调用该方法的对象的锁方能执行,否则所属线程阻塞,方法一旦执行,就独占该锁,直到从该方法返回时才将锁释放,此后被阻塞的线程方能获得该锁,重新进入可执行状态。

  2. 使用synchronized块对需要进行同步的代码段进行同步。

    synchronized 方法的缺陷:若将一个大的方法声明为synchronized 将会大大影响效率。Java 为我们提供了更好的解决办法,那就是 synchronized 块。 块可以让我们精确地控制到具体的“成员变量”,缩小同步的范围,提高效率。

     synchronized(syncObject){ 
     
         //允许访问控制的代码
    
     }
    复制代码

示例:

public class TestSync {
    public static void main(String[] args) {
        Account a1 = new Account(100, "高");
        Drawing draw1 = new Drawing(80, a1);
        Drawing draw2 = new Drawing(80, a1);
        draw1.start(); // 你取钱
        draw2.start(); // 你老婆取钱
    }
}
/*
 * 简单表示银行账户
 */
class Account {
    int money;
    String aname;
    public Account(int money, String aname) {
        super();
        this.money = money;
        this.aname = aname;
    }
}
/**
 * 模拟提款操作
 * 
 * @author Administrator
 *
 */
class Drawing extends Thread {
    int drawingNum; // 取多少钱
    Account account; // 要取钱的账户
    int expenseTotal; // 总共取的钱数
 
    public Drawing(int drawingNum, Account account) {
        super();
        this.drawingNum = drawingNum;
        this.account = account;
    }
 
    @Override
    public void run() {
        draw();
    }
 
    void draw() {
        synchronized (account) {
            if (account.money - drawingNum < 0) {
                System.out.println(this.getName() + "取款,余额不足!");
                return;
            }
            try {
                Thread.sleep(1000); // 判断完后阻塞。其他线程开始运行。
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            account.money -= drawingNum;
            expenseTotal += drawingNum;
        }
        System.out.println(this.getName() + "--账户余额:" + account.money);
        System.out.println(this.getName() + "--总共取了:" + expenseTotal);
    }
}
复制代码

转载于:https://juejin.im/post/5caeea7df265da039e1fde5e

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值