JAVA基础----同步锁
来源:互联网 发布:win8垃圾清理软件 编辑:程序博客网 时间:2024/05/17 04:13
同步机制:
解决多线程安全问题
同步代码块
格式:
synchronized (锁对象) {
需要同步的代码
}
(普通同步方法)
(静态同步方法)
格式:
修饰符 synchronized 返回值类型 方法名(参数列表){....}
同步方法,同步方法的锁对象是谁? this
同步方法,同步静态方法的锁对象是谁? 字节码文件对象, 类名.class
Lock锁: jdk1.5
void lock()获取锁。
死锁:
是指两个或者两个以上的线程在执行的过程中,因争夺资源(锁对象)产生的一种互相等待现象,下面是一段死锁的代码:
/*
等待:
感谢传智!
解决多线程安全问题
同步代码块
格式:
synchronized (锁对象) {
需要同步的代码
}
<span style="font-size:24px;">public void run() {<span style="white-space:pre"></span>int i = 1;</span>
<span style="font-size:24px;"></span>
<span style="font-size:24px;"><span style="white-space:pre"></span>while(i<100){</span>
<span style="font-size:24px;"><span style="white-space:pre"></span></span>
<span style="font-size:24px;"><span style="white-space:pre"></span>//需要是同一把锁才能起到作用<span style="white-space:pre"></span>synchronized (obj) {<span style="white-space:pre"></span>//需要被同步的内容,也就是需要多线程并发访问的内容</span>
<span style="font-size:24px;"><span style="white-space:pre"></span>System.out.println(i++);</span>
<span style="font-size:24px;"><span style="white-space:pre"></span>}</span>
<span style="font-size:24px;"><span style="white-space:pre"></span>}<span style="white-space:pre"></span></span>
<span style="font-size:24px;">}</span>
同步方法
(普通同步方法)
(静态同步方法)
格式:
修饰符 synchronized 返回值类型 方法名(参数列表){....}
</pre><pre name="code" class="java">//需要被多线程并发访问的同步方法
public synchronized void method(){
<span style="white-space:pre"></span>//方法内容<span style="font-family: Arial, Helvetica, sans-serif;"></span>
}
<pre name="code" class="java">//需要被多线程并发访问的静态同步方法
public static synchronized void method(){
<span style="white-space:pre"></span>
<span style="white-space:pre"></span>//方法内容
}
/*
<span style="white-space:pre"></span>它们的区别在于,所对象不同。
<span style="white-space:pre"></span>普通同步方法的锁对象是 tish
<span style="white-space:pre"></span>而静态同步方法的锁对象是 字节码文件对象:
<span style="white-space:pre"></span>类名.class
<span style="white-space:pre"></span>那用谁好呢?
<span style="white-space:pre"></span>它们的区别是:<span style="white-space:pre"></span>
<span style="white-space:pre"></span>静态与非静态,用谁就要看用静态还是不用静态
*/<span style="white-space:pre"></span>
注意:
同步方法,同步方法的锁对象是谁? this
同步方法,同步静态方法的锁对象是谁? 字节码文件对象, 类名.class
Lock锁: jdk1.5
void lock()获取锁。
void unlock()释放锁。
//新锁的使用与老锁一样,但它需要手动的释放锁。
<span style="white-space:pre"></span>int i=100;
<span style="white-space:pre"></span>//创建锁对象<span style="white-space:pre"></span>Lock lock=new ReentrantLock();
public void run(){
<span style="white-space:pre"></span><span style="white-space:pre"></span>while (true){
<span style="white-space:pre"></span>//加锁<span style="white-space:pre"></span>lock.lock();
<span style="white-space:pre"></span>//被同步的内容if (0<i){<span style="white-space:pre"></span>System.out.println(--i);}
<span style="white-space:pre"></span>//释放锁lock.unlock();}}
死锁:
是指两个或者两个以上的线程在执行的过程中,因争夺资源(锁对象)产生的一种互相等待现象,下面是一段死锁的代码:
public class ThreadList {public static void main(String[] args) {//创建两个多线程对象,并赋值DieThread die = new DieThread("帅哥", true);DieThread die1 = new DieThread("美女", false);//启动多线程die.start();die1.start();}}
<pre name="code" class="html">public class DieThread extends Thread {// 定义变量,用于判断被执行的代码public boolean flag;// 定义线程名称public String name;// 创建锁对象public static Object obj = new Object();public static Object obj1 = new Object();// 用于赋值的构造方法DieThread(String name, boolean flag) {this.name = name;this.flag = flag;};// 重写run方法public void run() {// 判断标签if (flag) {// 重复执行同步代码while (true) {// 锁1synchronized (obj1) {System.out.println(getName() + "obj----obj");// 锁0synchronized (obj) {System.out.println(getName() + "obj1---obj1");}}}} else {// 重复执行同步代码while (true) {// 锁0synchronized (obj) {System.out.println(getName() + "obj---obj");// 锁1synchronized (obj1) {System.out.println(getName() + "obj1---obj1");}}}}}}
/*
<span style="white-space:pre"></span>死锁是因为:
<span style="white-space:pre"></span>线程一拿到了锁1,正在判断锁0.
<span style="white-space:pre"></span>而线程二拿到了锁0,正在判断锁1.
<span style="white-space:pre"></span>因为同一个锁只能进入一个对象,所以线程一进不去已经存在对象的锁0,线程二也同理。但它们都有各自的任务,那就是解开下一个锁,所以它们都不会释放锁。
*/
等待:
wait(): 让当前的线程等待,释放锁对象,让其他线程获取锁对象与CPU执行权,
等待着其他线程 调用 notify()\notifyAll()来 唤醒
notify()\notifyAll() : 可以唤醒当前锁对象上面的等待的线程
notify(): 随机唤醒锁对象上面的其中一个等待的线程对象
//多生产多消费问题,等待唤醒机制
class Resource{private String name;private int count = 1;//定义标记。private boolean flag = false;//1,提供设置的方法。public synchronized void set(String name) {while(flag)
<span style="white-space:pre"></span>/*睡眠方法会抛出<code>terruptedException</code>异常
<span style="white-space:pre"></span> 如果在当前线程等待通知之前或者正在等待通知时
<span style="white-space:pre"></span> ,任何线程中断了当前线程。在抛出此异常时,
<span style="white-space:pre"></span> 当前线程的<em>中断状态</em> 被清除。
<span style="white-space:pre"></span>*/try{this.wait();}catch(InterruptedException e){}
//给成员变量赋值并加上编号。this.name = name + count;
//编号自增。count++;
//打印生产了哪个商品。System.out.println(Thread.currentThread().getName()+"......生产者...."+this.name);
//将标记改为true。flag = true;
//唤醒消费者。this.notifyAll();
}
<span style="white-space:pre"></span>
<span style="white-space:pre"></span>//消费方法public synchronized void out(){while(!flag)try{this.wait();}catch(InterruptedException e){}System.out.println(Thread.currentThread().getName()+"....消费者...."+this.name);
//将标记该为false。
flag = false;
//唤醒生产者。this.notifyAll();}}//2,描述生产者。class Producer implements Runnable{private Resource r ;
// 生产者一初始化就要有资源,需要将资源传递到构造函数中。Producer(Resource r){this.r = r;}public void run(){while(true){r.set("面包");}}}//3,描述消费者。class Consumer implements Runnable{private Resource r ;
// 消费者一初始化就要有资源,需要将资源传递到构造函数中。Consumer(Resource r){this.r = r;}public void run(){while(true){r.out();}}}class ThreadDemo10{public static void main(String[] args) {//1,创建资源对象。Resource r = new Resource();//2,创建线程任务。Producer pro = new Producer(r);Consumer con = new Consumer(r);//3,创建线程。Thread t1 = new Thread(pro);Thread t2 = new Thread(pro);Thread t3 = new Thread(con);Thread t4 = new Thread(con);t1.start();t2.start();t3.start();t4.start();}}
感谢传智!
0 0
- JAVA基础----同步锁
- Java基础-线程同步-锁
- Java基础之线程同步与锁
- java基础:线程同步
- java基础--线程同步
- Java基础--多线程|线程同步
- Java多线程基础之对象锁的同步与异步
- java并发编程之线程同步基础(二)使用锁实现同步
- 【Java基础】——之线程同步
- 黑马程序员----JAVA基础多线程&同步
- Java基础复习:线程同步练习
- Java基础——线程同步通信
- Java基础总结----多线程安全性&同步
- 学习java同步机制 (一) 基础篇
- 黑马程序员-----Java基础-----线程与同步
- Java语言基础之线程同步
- 2.Java基础:线程和同步
- 【java基础之多线程】线程同步
- codevs1050
- hdoj 2473 Junk-Mail Filter 【并查集的删除 】
- Effective C++ 学习记录
- Java远程调用RMI(Remote Method Invocation)
- TCP和UDP的“保护消息边界”(粘包、半包)
- JAVA基础----同步锁
- Ruby中的chop和chomp
- Slope one简单的协同过滤算法
- 杭电5285二分图染色和并查集
- 矩形面积并 POJ Atlantis
- ie浏览器前缀特殊符号的识别
- ZOJ 1002
- 包含cxf的应用程序部署在websphere8.5上
- 杭电OJ-1036_Average is not Fast Enough!