多线程2
来源:互联网 发布:求一些莆田鞋的淘宝店 编辑:程序博客网 时间:2024/05/19 23:15
synchronized使用
同步代码块:synchronized放在对象前面,限制一段代码的执行。锁可以是任意对象,但多个线程用的必须是同一把锁。
synchronized(锁对象){
需要同步的代码
}
同步方法:synchronized放在方法声明中,表示整个方法是同步方法。锁是this
public synchronized void method(){ }
静态同步方法:synchronized放在静态方法声明中,表示整个方法是同步方法。锁是字节码文件对象,类名.getclass()。
public static synchronized void method(){ }
同步特点:
好处:同步解决了多线程的安全问题
弊端:当线程很多时,每个线程都会判断同步上的锁,很耗费资源,降低程序的执行效率
容器类的线程安全:
可以用synchronized来锁住这个对象:
synchronized(list){
list.add(…);
}
可以使用java.uitl.Collections的synchronizedXXX()方法来返回一个同步化的容器对象
List list = Collections.synchronizedList(new ArrayList());
这种方式在迭代时仍要用synchronized修饰
List list = Collections.synchronizedList(new ArrayList()); ... synchronized(list) { Iterator i = list.iterator(); while (i.hasNext()) { foo(i.next()); } }
死锁
产生原因
有同步嵌套,两个线程都在等待对方已经锁定的资源。
public class TestDead { public static void main(String[] args) { RichMan man = new RichMan(); man.setName("富翁"); Kidnapper napper = new Kidnapper(); napper.setName("绑匪"); man.start(); napper.start(); }}class Lock { public static Object obj1 = new Object(); public static Object obj2 = new Object();}//描述富翁class RichMan extends Thread{ @Override public void run() { synchronized (Lock.obj1) { System.out.println("富翁说:你放了我儿子"); try { Thread.sleep(10); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } synchronized (Lock.obj2) { System.out.println("富翁说:我给你1000万"); } } }}//描述绑匪class Kidnapper extends Thread{ @Override public void run() { synchronized (Lock.obj2) { System.out.println("绑匪说:你给我1000万"); try { Thread.sleep(10); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } synchronized (Lock.obj1) { System.out.println("绑匪说:我放了你儿子"); } } }}
如何避免死锁:
一个通用的经验法则是:当几个线程都要访问共享资源(锁)A、B、C时,保证使每个线程都按照同样的顺序去访问它们,比如都先访问A,再访问B和C。
此外,Thread类的suspend()方法也很容易导致死锁,因此这个方法已经被废弃了.
线程的等待与唤醒(生产者与消费者问题)
notify(),wait()等是Object中方法,因为锁是任意对象,所有这么方法通过锁来使用
wait和sleep的区别:
1、sleep任何时候都可以调用,但是wait只能用在同步中。
2、sleep可以在规定时间内醒过来,但是wait需要唤醒,等待的时间是不确定。
3、sleep睡眠中不会交出锁,但是wait会交出同步锁。
生产者和消费者模型
package com.qianfeng.producecustomer;/* * 生产者生产6个,消费者6个 * 包子。 * 一个生产者,一个消费者。 * String * StringBuffer:同步的。效率不高 * StringBuilder:不同步的。效率高。很多时候是单线程。 * 扩展: * 线程池的概念。 * 作业: * 1:将生产多个和消费多个,改成集合和数组来实现。 * */public class TestProduce2 { public static void main(String[] args) { MyCustomer customer = new MyCustomer(); customer.start(); MyProduce produce = new MyProduce(); produce.start(); }}class MyBaozi{ public static int count = 0; public static final Integer SUM = 6;//总数。}class MyProduce extends Thread{ @Override public void run() { while(true){ //先判断。满了就等待。 synchronized (MyBaozi.SUM) { if(MyBaozi.count>=MyBaozi.SUM){ //等待 try { MyBaozi.SUM.wait(); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } //否则 MyBaozi.count++; try { Thread.sleep((int)(Math.random()*100)); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } System.out.println("生产者生产了一个包子,现有"+MyBaozi.count+"个包子"); MyBaozi.SUM.notify(); } } }}class MyCustomer extends Thread{ @Override public void run() { while(true){ synchronized (MyBaozi.SUM) { if(MyBaozi.count==0){ try { MyBaozi.SUM.wait(); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } //消费 MyBaozi.count--; try { Thread.sleep((int)(Math.random()*100)); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } System.out.println("消费者消费了一个包子,现有"+MyBaozi.count+"个包子"); MyBaozi.SUM.notify(); } } }}
- 多线程2
- 多线程2
- 多线程 - 2
- 多线程2
- 多线程2
- 多线程2
- 多线程-2
- 多线程2
- 多线程2
- 多线程2
- 多线程2
- 多线程2
- 多线程2
- 多线程-2
- 多线程2
- 多线程2
- 多线程(2):
- 多线程2
- 阿里云服务器使用SSH工具连接不上,并且ping不通,显示连接超时
- 【BZOJ1014】【JSOI2008】火星人prefix 哈希 非旋转treap
- 关于GPIO的学习
- jgit比较项目不同版本间的差异及统计代码总行数
- 前端之--前端代码规范
- 多线程2
- ajax 传对象数组到后台
- RobHess的SIFT源码图像特征点匹配
- BZOJ 4152 The Captain
- YOLO9000
- 蚁群算法(Java)tsp问题
- mongodb的分片(多字段),分片分裂原理
- 打开软件提示无法定位于动态链接库
- 排序(四):希尔排序