博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Java多线程(二) synchronized 针对对象进行锁定
阅读量:6296 次
发布时间:2019-06-22

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

 

1.方法内的变量为线程安全的

2.实例变量非线程安全的

public class HasSelfPrivateNum {        private int num = 0;    synchronized public void addI(String username) {        try {                        if (username.equals("a")) {                System.out.println("a set over");                num = 100;                Thread.sleep(2000);            }else{                num =200;                System.out.println("b set over");            }            System.out.println(username+" num="+num);        } catch (InterruptedException e) {            // TODO Auto-generated catch block            e.printStackTrace();        }    }}

ThreadA

public class ThreadA extends Thread{    private HasSelfPrivateNum numRef;        public ThreadA(HasSelfPrivateNum numRef){        this.numRef =numRef;    }        public void run(){        numRef.addI("a");    }}
View Code

ThreadB

public class ThreadB extends Thread{    private HasSelfPrivateNum numRef;        public ThreadB(HasSelfPrivateNum numRef){        this.numRef =numRef;    }        public void run(){        numRef.addI("b");    }}
View Code

Run

public class RunDemo {    public static void main(String[] args) {                HasSelfPrivateNum numRef = new HasSelfPrivateNum();                HasSelfPrivateNum numRef2 = new HasSelfPrivateNum();        ThreadA athread = new ThreadA(numRef);        athread.start();        ThreadB bthread = new ThreadB(numRef2);        bthread.start();    }}

例子不会发生脏读,因为是不同的对象

非线程安全其实会在多线程对同一个对象中的实例变量进行并发访问时发生,

产生的后果就是“脏读”,也就是取到的数据其实是被更改过的。

1)调用关键字synchronized声明的方法一定是排队运行的。只有共享资源的读写访问才需要同步化,如果不是共享资源,那么根本就没有同步的必要。

2)synchronized 同步块
不在synchronized块中就是异步执行,在synchronized块中就是同步执行
3)多个线程调用一个对象中的不同名称的synchronized同步方法或synchronized(this) 同步代码块时,调用的效果就是按顺序执行,也就是同步的,阻塞的。
4) 锁非this 对象具有一定的优点:如果在一个类中有很多个synchronized方法,这时
虽然能实现同步,但会受到阻塞,所以影响运行效率;但如果使用同步代码块锁非
this对象,则synchronized(this) 代码块中的程序与同步方法是异步的,不与其他锁this同步方法争抢this锁,则可以大大提高运行效率。
4.volatile 强制性从公共堆栈中进行取值,增加了实例变量在多个线程之间的可见性

public class Run {    public static void main(String[] args) throws InterruptedException {        Task task = new Task();        ThreadA threadA = new ThreadA(task);        threadA.setName("A");        threadA.start();        Thread.sleep(100);        ThreadB threadB = new ThreadB(task);        threadB.setName("B");        threadB.start();        }}
public class Task {    synchronized public void otherMethod() {        System.out.println("-----------run othermethod");    }    synchronized public void doLongTimeTask() {            for (int i = 0; i < 100; i++) {                try {                    Thread.sleep(100);                } catch (InterruptedException e) {                    // TODO Auto-generated catch block                    e.printStackTrace();                }                System.out.println("syn threadName=" + Thread.currentThread().getName() + "i=" + (i + 1));            }    }}

 

public class ThreadA extends Thread {    private Task task;        public ThreadA(Task task){        this.task =task;     }    public void run(){        task.doLongTimeTask();    }}public class ThreadB extends Thread {    private Task task;        public ThreadB(Task task){        this.task =task;     }    public void run(){        task.otherMethod();    }}

 

转载于:https://www.cnblogs.com/newlangwen/p/7568334.html

你可能感兴趣的文章
Spring: IOC容器的实现
查看>>
Serverless五大优势,成本和规模不是最重要的,这点才是
查看>>
Nginx 极简入门教程!
查看>>
iOS BLE 开发小记[4] 如何实现 CoreBluetooth 后台运行模式
查看>>
Item 23 不要在代码中使用新的原生态类型(raw type)
查看>>
为网页添加留言功能
查看>>
JavaScript—数组(17)
查看>>
Android 密钥保护和 C/S 网络传输安全理论指南
查看>>
以太坊ERC20代币合约优化版
查看>>
Why I Began
查看>>
同一台电脑上Windows 7和Ubuntu 14.04的CPU温度和GPU温度对比
查看>>
js数组的操作
查看>>
springmvc Could not write content: No serializer
查看>>
Python系语言发展综述
查看>>
新手 开博
查看>>
借助开源工具高效完成Java应用的运行分析
查看>>
163 yum
查看>>
第三章:Shiro的配置——深入浅出学Shiro细粒度权限开发框架
查看>>
80后创业的经验谈(转,朴实但实用!推荐)
查看>>
让Windows图片查看器和windows资源管理器显示WebP格式
查看>>