Java线程同步锁
把synchronized当作函数修饰符时,示例代码如下:
- Public synchronized void method(){
- //….
- }
这也就是同步方法,那这时synchronized锁定的是哪个对象呢?他锁定的是调用这个同步方法对象。也就是说,当一个对象P1在不同的线程中执行这个同步方法时,他们之间会形成互斥,达到同步的效果。但是这个对象所属的Class所产生的另一对象P2却能够任意调用这个被加了synchronized关键字的方法。
如同这样
- public void method()
- {
- synchronized (this) // (1)
- {
- //…..
- }
- }
此处的this指的是什么呢?他指的就是调用这个方法的对象,如P1。可见同步方法实质是将synchronized作用于object reference。――那个拿到了P1对象锁的线程,才能够调用P1的同步方法,而对P2而言,P1这个锁和他毫不相干,程式也可能在这种情形下摆脱同步机制的控制,造成数据混乱。具体使用像这样:
- package com.java.Thread;
- public class Mysynchronized {
- /**
- * @param args
- */
- public static void main(String[] args) {
- /*
- * GetTickets gt1 = new GetTickets(); GetTickets gt2 = new GetTickets();
- * GetTickets gt3 = new GetTickets(); gt1.setName("窗口一");
- * gt2.setName("窗口二"); gt3.setName("窗口三"); gt1.start(); gt2.start();
- * gt3.start();
- */
- GetTickets2 gt = new GetTickets2();
- Thread th1 = new Thread(gt, "窗口一");
- Thread th2 = new Thread(gt, "窗口二");
- Thread th3 = new Thread(gt, "窗口三");
- th1.start();
- try {
- Thread.sleep(500);
- } catch (InterruptedException e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- }
- gt.flag = true;
- th2.start();
- th3.start();
- }
- }
- class GetTickets2 implements Runnable {
- private int tickets = 10;
- boolean flag = false;
- /* Object ob = new Object();*/
- public void run() {
- if (flag) {
- for (int i = 0; i < 10; i++) {
- //synchronized (ob) {//如果用ob就无法同步
- synchronized (this) {
- if (tickets > 0) {
- try {
- Thread.sleep(500);
- } catch (InterruptedException e) {
- e.printStackTrace();
- }
- System.out.println(Thread.currentThread().getName()
- + "卖出" + (tickets--) + "号票"+":同步代码块");
- }
- }
- }
- } else {
- for (int i = 0; i < 10; i++) {
- function();
- }
- }
- }
- public synchronized void function() {
- if (tickets > 0) {
- try {
- Thread.sleep(500);
- } catch (InterruptedException e) {
- e.printStackTrace();
- }
- System.out.println(Thread.currentThread().getName() + "卖出"
- + (tickets--) + "号票"+":同步函数");
- }
- }
- }
- /*
- * class GetTickets extends Thread{ //private static int tickets = 10; private
- * int tickets = 10; public void run(){
- *
- * for (int i = 0; i < 10; i++) { if(tickets>0){
- * System.out.println(Thread.currentThread().getName()+"卖出"+(tickets--)+"号票"); }
- * } } }
- */
将synchronized作用于static 函数 同步的锁就是它自己本身的字节码,示例代码如下:
- Class Foo
- {
- public synchronized static void method1() // 同步的static 函数
- {
- //….
- }
- public void method2()
- {
- synchronized(Foo.class) // class literal(类名称字面常量)
- }
- }
具体代码如下
- package cn.java.thread;
/*
证明同步函数用的是this这把锁
*/
public class Tickets1 {
/**
* @param args
*/
public static void main(String[] args) {
/*
* GetTickets gt1 = new GetTickets(); GetTickets gt2 = new GetTickets();
* GetTickets gt3 = new GetTickets(); gt1.setName("窗口一");
* gt2.setName("窗口二"); gt3.setName("窗口三"); gt1.start(); gt2.start();
* gt3.start();
*/
GetTickets2 gt = new GetTickets2();
Thread th1 = new Thread(gt, "窗口一");
Thread th2 = new Thread(gt, "窗口二");
Thread th3 = new Thread(gt, "窗口三");
th1.start();
try {
Thread.sleep(500);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
gt.flag = true;
th2.start();
th3.start();
}
}
class GetTickets2 implements Runnable {
private static int tickets = 10;
boolean flag = false;
Object ob = new Object();
public void run() {
if (flag) {
for (int i = 0; i < 10; i++) {
//synchronized (this.getClass()) {
synchronized (GetTickets2.class) {
if (tickets > 0) {
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName()
+ "卖出" + (tickets--) + "号票"+":同步代码块");
}
}
}
} else {
for (int i = 0; i < 10; i++) {
function();
}
}
}
public static synchronized void function() {
if (tickets > 0) {
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + "卖出"
+ (tickets--) + "号票"+":同步函数");
}
}
}
/*
* class GetTickets extends Thread{ //private static int tickets = 10; private
* int tickets = 10; public void run(){
*
* for (int i = 0; i < 10; i++) { if(tickets>0){
* System.out.println(Thread.currentThread().getName()+"卖出"+(tickets--)+"号票"); }
* } } }
*/
然后嘞是 wait notify notifyall 这三个(两个)方法的 理解了 第一步 wait的作用是阻塞 notify的作用是唤醒
讲这个 要用到以前学到的生产者和消费者 对于他们的理解:
1.这些方法都存在与同步中
2;使用这些方法时必须要标记所属的同步锁
3:锁可以是任意对象,所以任意对象调用的方法一定定义在object类中 废话不多上代码:
这是同步代码块的
- package com.java.Thread;
- //定义一个rbq
- class Production{
- private String name;
- private String country;
- private boolean flag = true;
- public boolean isFlag() {
- return flag;
- }
- public void setFlag(boolean flag) {
- this.flag = flag;
- }
- public String getCountry() {
- return country;
- }
- public void setCountry(String country) {
- this.country = country;
- }
- public void setName(String name) {
- this.name = name;
- }
- public String getName() {
- return name;
- }
- }
- class Producer implements Runnable{
- private Production p = null;
- public Producer(Production p) {
- this.p = p;
- }
- public void run(){
- boolean b = true;
- while(true){
- synchronized (p) {
- if(p.isFlag()){
- //这个b就是打酱油的
- if(b){
- p.setName("李小文院士");
- p.setCountry("中国");
- b = false;
- }
- else{
- p.setName("加来道雄博士");
- p.setCountry("日本");
- b = true;
- }
- //唤醒 并且这里注意 把flag改变成了 false
- p.setFlag(false);
- p.notify();
- }
- else
- try {
- //老样子 否则就过来阻塞
- p.wait();
- } catch (Exception e) {
- // TODO: handle exception
- }
- }
- }
- }
- }
- class Saler implements Runnable{
- private Production p = null;
- //表明同步的锁!!!!
- public Saler(Production p) {
- this.p = p;
- }
- public void run() {
- while(true){
- synchronized (p) {
- //上面的 isFlage被设定成 false了 所以这里要不等于 然后他们 就这样一直轮回下去 下面没了就让上面造
- if(!p.isFlag()){
- //获取前面的 赋值
- System.out.println(p.getName()+":"+p.getCountry());
- p.setFlag(true);
- //唤醒 动起来
- p.notify();
- }
- else{
- try {
- //阻塞
- p.wait();
- } catch (Exception e) {
- // TODO: handle exception
- }
- }
- }
- }
- }
- }
- public class ProductionDemo{
- public static void main(String[] args) {
- Production p = new Production();
- Producer producer = new Producer(p);
- Saler saler = new Saler(p);
- Thread th1 = new Thread(producer);
- Thread th2 = new Thread(saler);
- th1.start();
- th2.start();
- }
- }
小钢炮这个是同步函数的
- public class ProductionDemo{
- public static void main(String[] args) {
- // 这是同步函数的
- /* Production p = new Production();
- Producer producer = new Producer(p);
- Saler saler = new Saler(p);
- Thread th1 = new Thread(producer);
- Thread th2 = new Thread(saler);
- th1.start();
- th2.start();
- */
- //同步代码块
- Production p = new Production();
- Producer pd = new Producer(p);
- Saler s = new Saler(p);
- Thread th1 = new Thread(pd);
- Thread th2 = new Thread(s);
- th1.start();
- th2.start();
- }
- }
- //同步代码块
- class Production {
- private String name;
- private int num = 0;
- private boolean b = false;
- public boolean isB() {
- return b;
- }
- public void setB(boolean b) {
- this.b = b;
- }
- public String getName() {
- return name;
- }
- public void setName(String name) {
- this.name = name;
- }
- public int getNum() {
- return num;
- }
- public void setNum(int num) {
- this.num = num;
- }
- }
- class Producer implements Runnable {
- private Production p = null;
- public Producer(Production p) {
- this.p = p;
- }
- public void run() {
- while (true) {
- synchronized (p) {
- if (p.isB()) {
- try {
- p.wait();
- } catch (InterruptedException e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- }
- }
- p.setName("小钢炮");
- p.setNum(p.getNum() + 1);
- System.out.println("生产:" + p.getName() + p.getNum());
- p.setB(true);
- p.notify();
- }
- }
- }
- }
- class Saler implements Runnable {
- private Production p = null;
- //获取定义的锁要一样
- public Saler(Production p) {
- this.p = p;
- }
- public void run() {
- while (true) {
- synchronized (p) {
- if (!p.isB()) {
- try {
- //阻塞
- p.wait();
- } catch (InterruptedException e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- }
- }
- System.out.println("卖:" + p.getName() + p.getNum());
- p.setB(false);
- //唤醒
- p.notify();
- }
- }
- }
- }
然后了是多生产者和多消费者 嘿嘿上码:
- package cn.java.thread1;
- public class ProductionDemo2 {
- /**
- * @param args
- */
- public static void main(String[] args) {
- Production2 p = new Production2();
- Producer2 pd = new Producer2(p);
- Saler2 s = new Saler2(p);
- Thread th1 = new Thread(pd);
- Thread th2 = new Thread(pd);
- Thread th3 = new Thread(s);
- Thread th4 = new Thread(s);
- Thread th5 = new Thread(pd);
- Thread th6 = new Thread(s);
- th1.start();
- th2.start();
- th3.start();
- th4.start();
- th5.start();
- th6.start();
- }
- }
- class Production2 {
- private String name;
- private int num = 0;
- private boolean b = false;
- public boolean isB() {
- return b;
- }
- public void setB(boolean b) {
- this.b = b;
- }
- public String getName() {
- return name;
- }
- public void setName(String name) {
- this.name = name;
- }
- public int getNum() {
- return num;
- }
- public void setNum(int num) {
- this.num = num;
- }
- public synchronized void produce() {
- //if (b) {
- while (b) {
- try {
- this.wait();
- } catch (InterruptedException e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- }
- }
- setName("小钢炮");
- setNum(getNum() + 1);
- System.out.println("生产:" + getName() + getNum());
- setB(true);
- //notify();
- notifyAll();
- }
- public synchronized void sale() {
- //if (!b) {
- while(!b){
- try {
- this.wait();
- } catch (InterruptedException e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- }
- }
- System.out.println("卖:" + getName() + getNum());
- setB(false);
- //notify();
- notifyAll();
- }
- }
- class Producer2 implements Runnable {
- private Production2 p = null;
- public Producer2(Production2 p2) {
- this.p = p2;
- }
- public void run() {
- for (int i = 0; i < 100; i++) {
- p.produce();
- }
- }
- }
- class Saler2 implements Runnable {
- private Production2 p = null;
- public Saler2(Production2 p2) {
- this.p = p2;
- }
- public void run() {
- for (int i = 0; i < 100; i++) {
- p.sale();
- }
- }
- }
Java线程同步锁的更多相关文章
- java 线程同步 原理 sleep和wait区别
java线程同步的原理java会为每个Object对象分配一个monitor, 当某个对象(实例)的同步方法(synchronized methods)被多个线程调用时,该对象的monitor将负责处 ...
- 【总结】Java线程同步机制深刻阐述
原文:http://hxraid.iteye.com/blog/667437 我们可以在计算机上运行各种计算机软件程序.每一个运行的程序可能包括多个独立运行的线程(Thread). 线程(Thread ...
- Java线程同步_1
Java线程同步_1 synchronized 该同步机制的的核心是同步监视器,任何对象都可以作为同步监视器,代码执行结束,或者程序调用了同步监视器的wait方法会导致释放同步监视器 synchron ...
- Java线程同步之一--AQS
Java线程同步之一--AQS 线程同步是指两个并发执行的线程在同一时间不同时执行某一部分的程序.同步问题在生活中也很常见,就比如在麦当劳点餐,假设只有一个服务员能够提供点餐服务.每个服务员在同一时刻 ...
- Java线程:锁
一.锁的原理 Java中每个对象都有一个内置锁,当程序运行到非静态的synchronized同步方法上时,自动获得与正在执行的代码类的当前实例(this实例)有关的锁.获得一个对象的锁也称为获取锁.锁 ...
- JAVA - 线程同步和线程调度的相关方法
JAVA - 线程同步和线程调度的相关方法 wait():使一个线程处于等待(阻塞)状态,并且释放所持有的对象的锁:wait是Object类的方法,对此对象调用wait方法导致本线程放弃对象锁,进入等 ...
- Java线程同步的四种方式详解(建议收藏)
Java线程同步属于Java多线程与并发编程的核心点,需要重点掌握,下面我就来详解Java线程同步的4种主要的实现方式@mikechen 目录 什么是线程同步 线程同步的几种方式 1.使用sync ...
- java线程 同步临界区:thinking in java4 21.3.5
java线程 同步临界区:thinking in java4 21.3.5 thinking in java 4免费下载:http://download.csdn.net/detail/liangru ...
- Python之路(第四十四篇)线程同步锁、死锁、递归锁、信号量
在使用多线程的应用下,如何保证线程安全,以及线程之间的同步,或者访问共享变量等问题是十分棘手的问题,也是使用多线程下面临的问题,如果处理不好,会带来较严重的后果,使用python多线程中提供Lock ...
随机推荐
- java并发包分析之———BlockingQueue
一.概述: BlockingQueue作为线程容器,可以为线程同步提供有力的保障. 二.BlockingQueue定义的常用方法 1.BlockingQueue定义的常用方法如下: 抛出异常 ...
- 全局程序集缓存GAC
GAC中的所有的Assembly都会存放在系统目录"%winroot%\assembly下面.放在系统目录下的好处之一是可以让系统管理员通过用户权限来控制Assembly的访问. 目录:C: ...
- 在Django中使用Neo4j
重要的先说在前面吧,最后的选型结构是安装了最新的neo4j版本3.0.3,使用了neo4j-rest-client客户端库.主要原因是更适用于django的neomodel库目前只支持neo4j2.2 ...
- Fiddler抓包使用教程-断点调试
转载请标明出处:http://blog.csdn.net/zhaoyanjun6/article/details/62896784 本文出自[赵彦军的博客] Fiddler 里面的断点调试有2种方式. ...
- Vue--学习过程中遇到的坑
在这里总结一下学习Vue遇到的易错点,持续更新 1.实例化一个Vue对象: 通过new Vue({ el:'#id', data:{ a:'字符串1', b:‘字符串2’ }) 这里的Vue必须大写V ...
- 第一章 C++概述
第一节 C++语言的发展历史 略 第二节 C++语言的特点 1.C++是一种面向对象的程序设计语言,其中的新技术主要包括: 抽象数据类型 封装和信息隐蔽 以继承和派生方式实现程序的重用 以运算符重载和 ...
- windows下安装mysql-5.7.11-winx64
1.解压. 2.将『D:\Program Files\mysql-5.7.11-winx64\bin』加入系统环境变量. 3.修改my-default.ini. 4.初始化data目录,在 ...
- git-------基础(一)
更改连接仓库只用操作一次(先删后加) (1)git remote rm origin //若本地已经关联了一个远程库,则先删除已关联的 ...
- 升讯威微信营销系统开发实践:(4)源代码结构说明 与 安装部署说明( 完整开源于 Github)
GitHub:https://github.com/iccb1013/Sheng.WeixinConstruction因为个人精力时间有限,不会再对现有代码进行更新维护,不过微信接口比较稳定,经测试至 ...
- Map集合学习总结
1.Map接口定义的集合又称查找表,用于存储所谓的 key-value 映射对,key可以看成是value的索引,作为key的对象在集合中不可以重复 根据内部数据结构的不同Map接口有多重实现类,其 ...