Java多线程基础(synchronized同步方法详解)

文章目录

    • 例子
    • 线程基础
      • 创建和运行
    • 线程同步
    • 协调同步的线程

例子

无法执行两个无限循环,按照程序执行的顺序,必然会一直执行第一个无限循环体而无法执行第二个循环体。

若通过两个线程来执行循环体AB,线程A和B会轮流获得CPU处理,两个循环体都可以执行啦!可以说通过线程,两个死循环变成了一个,把CPU卡住了。

线程基础

创建和运行

用Thread类创建线程对象,需要重写Thread类的run()方法,run方法中规定线程所要作的操作。

 //继承Thread类
public class B extends Thread{

    public void run() {
        ......
    }
    
}
//main函数
public static void main(String args[]) {
    A thread = new Thread();//创建线程
    thread.start();//启动线程,会自动调用run()方法
}

使用Thread类直接创建线程对象,第一个参数是实现Runnable接口类的实例。优点是便于多个线程的变量共享

public A protask implements Runnable{

    @Override
    public void run() {
        ......
    }
    
}

//main函数
public static void main(String args[]) {
    A target = new A();
    Thread thread = new Thread(A);//
    thread.start();//启动线程,会自动调用run()方法
}

线程同步

例子 程序语言
出纳和会计共用同一账户 线程SaveA,TakeB共享同一变量
取钱和存钱的操作不能同时进行 不允许多个线程同时修改同一变量
取钱时不允许存钱 允许TakeB线程取钱操作,禁止SaveA线程存钱操作
存钱时不允许取钱 允许SaveA线程存钱操作,禁止TakeB线程取钱操作

要实现存取的互斥,需要使用synchronized关键字修饰函数方法。当线程A使用了synchronized(同步)方法时,线程B想要执行同步方法,必须等待A执行完该方法。

public class account implements Runnable{
    int amount;//共享变量
    @Override
    public void run() {
    saveOrtake();//同步方法
    }
}

public synchronized void saveOrtake(){
    if(Thread.currentThread().getName().equals(SaveA)){
        //存钱
    }
    else{
        //取钱
    }
}

协调同步的线程

当一个线程使用同步方法中用到的某一个变量,而此变量需要其他线程修改之后才能符合线程的需要时,参考下面的例子:

例子 程序语言
出纳想取钱但发现账户金额<=0时,出纳不能取钱,等待会计存钱 TakeB线程等待,将CPU使用权让出,SaveA线程继续执行
经会计存钱,账户金额>0,出纳继续取钱 唤醒TakeB线程执行取钱操作
public class account implements Runnable{
    int amount;//共享变量
    @Override
    public void run() {
    saveOrtake();//同步方法
    }
}

public synchronized void saveOrtake(){
    if(Thread.currentThread().getName().equals(SaveA)){
        //存钱
        if(amount>0)notifyAll();//唤醒所有进程
    }
    else{
        if(amount <=0) wait();//线程等待,直到金额大于0后将其唤醒,执行取钱操作
        //取钱
    }
}

注意:notify(), notifyAll(), wait()只能在同步方法中使用

你可能感兴趣的:(java,开发语言,后端,多线程)