博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
多线程学习 synchronized加锁 保持数据一致 四
阅读量:4179 次
发布时间:2019-05-26

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

java中任何对象默认都会有一个互斥锁标记,用来分配给线程。也可以选择这个所标记 没有分配给任何线程/或者只能给一个线程。 只有拿到对象所标记的线程才能进入到对该对象加锁的同步代码块。 同步锁的是对象 线程退出同步代码块(线程执行完毕 确切来说,run方法执行完毕),会释放相应的锁标记。

synchronized 修饰代码块 对象锁标记 上代码

package com.baigu.demo1.stack;public class TestStack {    public static void main(String[] args) throws InterruptedException {        Stack stack = new Stack();//        stack.print();//        stack.posh('C');//        stack.print();//        stack.pop();//        stack.print();        PushThread t1 = new PushThread(stack);        PopThread t2 = new PopThread(stack);        stack.print();        System.out.println();        t1.start();        t2.start();        Thread.sleep(1000); //睡一秒让t1 t2线程执行结束在执行主线程        stack.print();    }}class Stack{    private char[] data={'A','B',' ',' ',' ',' ',' ',' '};    private int index=2;    //记录数组中有效元素的个数    public void posh(char c){        System.out.println(c+"  poshed! 入栈");        data[index]=c;        try {            Thread.sleep(1000);        //睡0.1秒类似于时间片到期        } catch (InterruptedException e) {            e.printStackTrace();        }        index++;    }    public void  pop(){        index --;        System.out.println(data[index]+"  poped!  出栈");        data[index]=' ';    }    public void print(){        for (char s:data)            System.out.print(s);    }}class PushThread extends Thread{    Stack s;    public PushThread(Stack s) {        this.s = s;    }    @Override    public void run() {//        s.posh('C');        synchronized (s){       //同步代码块     参数为对象的引用        对象锁标记            s.posh('C');        }    }}class PopThread extends Thread{    Stack s;    public PopThread(Stack s) {        this.s = s;    }    @Override    public void run() {        synchronized (s){       //同步代码块     参数为对象的引用    对象锁标记            s.pop();        }    }}

synchronized 修饰方法 方法锁标记 上代码

package com.baigu.demo1.stack;public class Testsynchronizedmethod {    public static void main(String[] args) throws InterruptedException {        StackTwo stack = new StackTwo();        PushThreadTwo t1 = new PushThreadTwo(stack);        PopThreadTwo t2 = new PopThreadTwo(stack);        stack.print();        System.out.println();        t1.start();        t2.start();        Thread.sleep(1000); //睡一秒让t1 t2线程执行结束在执行主线程        stack.print();    }}class StackTwo{    private char[] data={'A','B',' ',' ',' ',' ',' ',' '};    private int index=2;    //记录数组中有效元素的个数    public synchronized void posh(char c){      //方法锁标记        System.out.println(c+"  poshed! 入栈");        data[index]=c;        try {            Thread.sleep(800);        //睡0.1秒类似于时间片到期        } catch (InterruptedException e) {            e.printStackTrace();        }        index++;    }    public synchronized void  pop(){         //方法锁标记        index --;        System.out.println(data[index]+"  poped!  出栈");        data[index]=' ';    }    public void print(){        for (char s:data)            System.out.print(s);    }}class PushThreadTwo extends Thread{    StackTwo s;    public PushThreadTwo(StackTwo s) {        this.s = s;    }    @Override    public void run() {            s.posh('C');    }}class PopThreadTwo extends Thread{    StackTwo s;    public PopThreadTwo(StackTwo s) {        this.s = s;    }    @Override    public void run() {            s.pop();    }}

synchronized锁机制 无论是同步代码块还是作为修饰符 两种本质相同

下面是做的一些总结

线程同步:当多线程并发访问临界资源(同一个对象)时,多线程同时访问同一个对象时,如果破坏了原子操作(不可分割的操作),就会造成数据不一致。和数据库中的事务类似。1.synchronized(o){}: 对对象o加锁的同步代码块  同步代码块保护原子操作不被破坏。个人理解:主线程运行优于自己创建的线程运行。java中任何对象默认都会有一个互斥锁标记,用来分配给线程。也可以选择这个所标记没有分配给任何线程/或者只能给一个线程。只有拿到对象所标记的线程才能进入到对该对象加锁的同步代码块。同步锁的是对象线程退出同步代码块(线程执行完毕 真正意义上,run方法结束),会释放相应的锁标记。2.synchronized(用作方法修饰符),synchronized修饰的方法叫做同步方法  同步方法指的是在整个方法的范围内对当前对象加锁。只有拿到对象所标记的线程才能调用该对象的同步方法。同步方法等同于同步代码块。锁池:任何对象都有的一个空间,用来存放等待该对象锁标记的线程 (一个或多个)利用锁机制解决线程的同步问题,只有拿到对象所标记的线程才能进入到对该对象加锁的同步代码块(原子操作)。

线程架构图

在这里插入图片描述
纠正一点,较之前说的五中状态,现在又增加了一种 锁池状态。

这辈子坚持与不坚持都不可怕,怕的是独自走在坚持的道路上。 欢迎加入技术群聊。

在这里插入图片描述

转载地址:http://nkoai.baihongyu.com/

你可能感兴趣的文章
android中SharedPreferences的简单例子
查看>>
android中使用TextView来显示某个网址的内容,使用<ScrollView>来生成下拉列表框
查看>>
andorid里关于wifi的分析
查看>>
Hibernate和IBatis对比
查看>>
Spring MVC 教程,快速入门,深入分析
查看>>
Android 的source (需安装 git repo)
查看>>
Ubuntu Navicat for MySQL安装以及破解方案
查看>>
java多线程中的join方法详解
查看>>
在C++中如何实现模板函数的外部调用
查看>>
HTML5学习之——HTML 5 拖放
查看>>
HTML5学习之——HTML 5 应用程序缓存
查看>>
HTML5学习之——HTML 5 Web Workers
查看>>
HTML5学习之——HTML 5 Canvas
查看>>
HTML5学习之——HTML5 内联 SVG
查看>>
HTML5学习之——HTML 5 服务器发送事件
查看>>
SVG学习之——HTML 页面中的 SVG
查看>>
SVG 形状学习之——SVG圆形
查看>>
SVG 滤镜学习之——SVG 滤镜
查看>>
mysql中用命令行复制表结构的方法
查看>>
hbase shell出现ERROR: org.apache.hadoop.hbase.ipc.ServerNotRunningYetException
查看>>