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 ...
随机推荐
- ORACLE之TO_DATE (转载)
转自 http://www.cnblogs.com/anran_guojianjun/archive/2009/09/11/1564535.html 一.在使用Oracle的to_date函数来做日期 ...
- MySQL/MariaDB中的事务和事务隔离级别
本文目录:1.事务特性2.事务分类 2.1 扁平事务 2.2 带保存点的扁平事务 2.3 链式事务 2.4 嵌套事务 2.5 分布式事务3.事务控制语句4.显式事务的次数统计5.一致性非锁定读(快照查 ...
- Django Web项目代码规范参考
Python:PEP8+GoogleStyle+DjangoSytlePEP8中文版:http://www.cnblogs.com/huazi/archive/2012/11/28/2792929.h ...
- sharesdk for android集成调试的几个问题
1.一定要下载最新版,这个东西目前版本升级很频繁,证明产品本身还不稳定,最新版bug会少一点 2.下载最新版SDK的时候,跟随下载最新Sample,官网文档的示例代码及时性很差. 3.调试的几个Key ...
- Qt中的ui指针和this指针
初学qt,对其ui指针和this指针产生疑问,画了个把小时终于搞懂了. 首先看ui指针的定义: 在mainwindow.h中 private: Ui::MainWindow *ui; Ui又是什么? ...
- 一个简单的PHP模板引擎
PHP早期开发中通常是PHP代码和HTML代码混写,这也使代码中充斥着数据库操作,逻辑处理等.当项目不大时,这样的代码还可以接受,但是随着项目不断扩大,我们就会发现同一个文件中同时存在前端逻辑和后端处 ...
- 构建基础的SpringMVC+Hibernate+SpringloC项目
一. SpringMVC 阅读我的上一篇文章<使用MyEclipse2015构建SpringMVC项目>,知道基本的构建方法,先构建一个纯springmvc项目,再对web.xml按照本文 ...
- python while 循环语句
Python 编程中 while 语句用于循环执行程序,即在某条件下,循环执行某段程序,以处理需要重复处理的相同任务.其基本形式为: while 判断条件: 执行语句-- 执行语句可以是单个语句或语句 ...
- 洛谷 P1879 解题报告
P1879 [USACO06NOV]玉米田Corn Fields 题目描述 农场主\(John\)新买了一块长方形的新牧场,这块牧场被划分成\(M\)行\(N\)列\((1 ≤ M ≤ 12; 1 ≤ ...
- JavaScript(二、BOM 浏览器对象模型)
一.BOM是什么 BOM是browser object model的缩写,简称浏览器对象模型 BOM提供了独立于内容而与浏览器窗口进行交互的对象 由于BOM主要用于管理窗口与窗口之间的通讯,因此其核心 ...