多线程并发保护机制有哪些?java多线程详解

TheDisguiser 2020-06-17 20:12:57 java常见问答 5497

我们知道,在java中有着进程和线程之分,而线程又有着多线程来处理各种高并发问题,但在实现高并发时可能会出现各种情况,下面我们就来看看多线程的并发保护机制有哪些吧。

一、文件锁

如果对一个表更新或插入的操作都会经过一个统一的文件,那么这种方式就可以解决多线程并发问题

例:

public static
function cbInventoryReserve()
{
    $LOCK_FILE_PATH = $_SERVER['DOCUMENT_ROOT'].
    "wmsinventoryapi/inventory/InventoryReserve.php";
    $fp = fopen($LOCK_FILE_PATH, "r");
    if (!$fp)
    {
        die("Failed to open the lock file!");
    }
    flock($fp, LOCK_EX);
    //需要进行的操作
    $params = Flight::request() - > getBody();
    $params = json_decode($params, true);
    if (!is_array($params) || empty($params))
    {
        Flight::sendRouteResult(array("error_code" => "40002", "error_info" => "params empty"));
    }
    $result = Inventory InventoryEngine::getInstance() - > inventoryReserve($params);
    flock($fp, LOCK_UN);
    fclose($fp);
    Flight::sendRouteResult($result);
}

二、synchronized关键字

特点:

a) 当两个并发线程访问同一个对象object中的synchronized(this)同步代码块时,一个时间内只能有一个线程得到执行,另一个线程必须等待当前线程执行完这个代码块以后才能执行该代码块。

b) 当一个线程访问object的一个synchronized(this)同步代码块时,其他线程对object中所有其它synchronized(this)同步代码块的访问将被阻塞。

例:

package thread;
//定义银行类
class Blank
{
    private int sum; //银行总共的存款
    private Object obj = new Object();
    public void add(int num)
    {
        synchronized(obj)
        { //这里的obj相当于一把锁
            sum = sum + num;
            try
            {
                Thread.sleep(1000); //这里我们让线程睡一秒钟,这样cpu时间片可以充分的切换到其他线程上
            }
            catch (InterruptedException e)
            {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            System.out.println("sum=" + sum);
        }
    }
}
//定义储户类
class Customer implements Runnable
{
    Blank blank = new Blank();
    @Override
    public void run()
    {
        //每个储户往银行循环存三次钱,每次100
        for (int i = 0; i < 3; i++)
        {
            blank.add(100);
        }
    }
}
public class ThreadDemo3
{
    public static void main(String[] args)
    {
        //创建实现了Runable接口的线程任务对象
        Customer customer = new Customer();
        Thread t1 = new Thread(customer);
        Thread t2 = new Thread(customer);
        Thread t3 = new Thread(customer);
        //开启三条线程模拟三个储户存款
        t1.start();
        t2.start();
        t3.start();
    }
}

三、Lock

Lock是控制多个线程对共享资源进行访问的工具,我们知道,锁机制提供了对共享资源的独占访问,线程会对Lock对象加锁,所以在开始访问共享资源之前,我们应该先获得Lock对象。

例:

package thread;
import java.util.concurrent.locks.ReentrantLock;
/**
 * @auto dh
 * @create 
 */
class Account {
    private Double balance;
    private ReentrantLock lock=new ReentrantLock();
    public Account(Double balance) {
        this.balance = balance;
    }
    public void deposite(Double amt) {
        try {
            lock.lock();
            if (amt > 0) {
                balance += amt;
            }
            System.out.println(Thread.currentThread().getName() + ":存款成功,余额为" + balance);
        }finally {
            lock.unlock();
        }
    }
}
class Customer extends Thread {
    private Account account;
    public Customer(Account account) {
        this.account = account;
    }
    public void run() {
        for (int i = 0; i < 3; i++) {
            this.account.deposite(1000.0);
        }
    }
}
public class Thread005 {
    public static void main(String[] args) {
        Account account=new Account(0.0);
        Customer customerA=new Customer(account);
        Customer customerB=new Customer(account);
        customerA.setName("张三");
        customerB.setName("李四");
        customerA.start();
        customerB.start();
    }
}

以上就是关于多线程并发保护机制的所有内容了,更多相关java架构师详细内容请持续关注奇Q工具网了解具体详情吧。

推荐阅读:

java多线程实例,java线程之间如何通信?

java实现多线程的方法,java中实现多线程的几种方法介绍

怎样创建多线程?多线程概念有哪些?