博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
多线程(3)
阅读量:4564 次
发布时间:2019-06-08

本文共 2388 字,大约阅读时间需要 7 分钟。

1.为什么使用synchronized和java.util.concurrent.locks.Lock?

1>线程不安全,因为线程是随机的,它可以随机访问你可见的共享变量。如果共享变量被修改,对另一个线程操作来说,它的数据就不准确

2>数据不安全,数据被共享

即共享变量、可见性和原子性

3>指令重排序(as-if-serial)

 

   加锁,是只一个线程可以访问,其他线程等待访问的线程结束,后面的线程由cpu随机分配访问。

*线程状态

线程状态:创建->就绪->运行->死亡

线程从就绪状态被唤醒,运行时,有其他线程正在运行且访问的是它要访问的内容,那么,它会阻塞。

阻塞->就绪

休眠状态:即等待(阻塞)状态

运行时,如果cpu随机分配线程抢占了当前线程的资源,该线程进入就绪状态。

public class Account {    private long money = 0;//余额        public Account(){}        public long cunQian(int num){
//存钱 money = money + num; return num; } public long quQian(int num){
//取钱 money = money - num; return num; } public long getMoney(){ return money; }}
import java.util.Random;public class Thread02 extends Thread{    private Account acc = null;    public Thread02(Account acc){        this.acc = acc;    }    @Override    public void run() {        long cunQian = acc.cunQian(new Random().nextInt(1000));        System.out.println("存了:"+cunQian+";账户内有:"+acc.getMoney());        long quQian = acc.quQian(new Random().nextInt(1000));        System.out.println("取了:"+quQian+";账户内有:"+acc.getMoney());    }}

无锁

public class Thread02Main {    public static void main(String[] args) {        Account acc = new Account();        Thread02 t1 = new Thread02(acc);        Thread02 t2 = new Thread02(acc);        Thread02 t3 = new Thread02(acc);        t1.start();        t2.start();        t3.start();            }}

 

*无序且数据错误(效果和有锁比较)

 

 

有锁

import java.util.Random;public class Thread02 extends Thread{    private Account acc = null;    public Thread02(Account acc){        this.acc = acc;    }    @Override    public void run() {        synchronized (acc) {            long cunQian = acc.cunQian(new Random().nextInt(1000));            System.out.println("存了:"+cunQian+";账户内有:"+acc.getMoney());            long quQian = acc.quQian(new Random().nextInt(1000));            System.out.println("取了:"+quQian+";账户内有:"+acc.getMoney());        }    }}
public class Account {    private long money = 0;        public Account(){}        public synchronized long cunQian(int num){
//存钱 money = money + num; return num; } public synchronized long quQian(int num){
//取钱 money = money - num; return num; } public long getMoney(){ return money; }} *先存后取,账户数据正确。负数是因为存取钱是随机数。

转载于:https://www.cnblogs.com/zzlcome/p/11085343.html

你可能感兴趣的文章
JavaScript 回车键转成Tab键
查看>>
CentOS7配置MySQL5.7主备
查看>>
合并区间(LintCode)
查看>>
mysql索引的创建
查看>>
《 BCG 原创 :系列 三》 添加菜单栏
查看>>
Java中关于CyclicBarrier的使用
查看>>
vsftpd配置教程
查看>>
first ios app
查看>>
论javascript模块化的优缺
查看>>
css 冷门样式大全
查看>>
MYSQL 服务无法启动,错误日志:InnoDB: .\ibdata1 must be writable
查看>>
Java并发包基石-AQS详解
查看>>
Stopwatch运行时间 Parallel并行任务
查看>>
angular 事件绑定
查看>>
干货型up主
查看>>
线程池
查看>>
需求:打印九九乘法表
查看>>
5 OK6410裸机调试(不用Jlink)
查看>>
今天实现一个T-sql的小编程,分享给大家,看看就好~(列值赋值)
查看>>
“模板”学习笔记(5)-----编译器在处理函数模板的时候都干了啥
查看>>