【知识点整理(Java)】Java Thread简单使用注意点汇总(二)
2015-10-25 14:51
661 查看
一、处理多线程的步骤
确定同步前提用synchronized解决安全问题
用线程通信解决逻辑顺序
二、有关锁的问题
wait和notify的理解是对共享资源的锁的管理,而不是对线程的管理。因此wait和notify必须在拥有锁的线程中使用,即在synchronized修饰的代码块中使用。
三、多线程的处理实践
两个思路,一是在主线程中处理同步,二是在资源文件中处理同步。在线程中处理同步:
public class CommunicateTread { public static void main(String[] args) { Res res = new Res("木木", "男"); new Thread(new Input(res)).start(); new Thread(new Output(res)).start(); } } class Input implements Runnable { private Res res; private int i; public Input(Res res) { this.res = res; } @Override public void run() { while (true) { synchronized (res) { if (res.flag) { try { res.wait(); } catch (InterruptedException e) { e.printStackTrace(); } } if (i == 0) { res.name = "呆呆"; res.sex = "女"; } else { res.name = "木木"; res.sex = "男"; } res.flag = true; res.notify(); } i = ++i % 2; } } } class Output implements Runnable { private Res res; public Output(Res res) { this.res = res; } @Override public void run() { while (true) { synchronized (res) { if(!res.flag){ try { res.wait(); } catch (InterruptedException e) { e.printStackTrace(); } } System.out.println("此时name为 " + res.name + " sex为 " + res.sex); res.flag = false; res.notify(); } } } } class Res { //此标志为需求逻辑上的标记,不可和对象锁混淆。 boolean flag;// true 为为打印,false 为可修改 String name; String sex; public Res(String name, String sex) { this.name = name; this.sex = sex; } }
优化,对资源存取方式处理同步,重写Res,Input,Output类:
代码略,见下文生产消费者代码。
#### 四、经典的生产者消费者 1、两个线程,一个为生产者,一个为消费者。 2、多个线程,if判断标记 改为 while循环一直在检测标志;notify改为notifyAll。
package thread;
public class ClassicalThread {
public static void main(String[] args) { Resourse res = new Resourse(); new Thread(new Producer(res)).start(); new Thread(new Producer(res)).start(); new Thread(new Producer(res)).start(); new Thread(new Resumer(res)).start(); new Thread(new Resumer(res)).start(); new Thread(new Resumer(res)).start(); }
}
class Resourse {
private String name; private int id = 0; private boolean flag = true; public synchronized void produce(String name) { while (!flag) { try { wait(); } catch (InterruptedException e) { e.printStackTrace(); } } this.name = name; System.out.println("生产" + name + " " + ++id); flag = false; notifyAll(); } public synchronized void resume() { while (flag) { try { wait(); } catch (InterruptedException e) { e.printStackTrace(); } } System.out.println("消费" + name + " " + id); flag = true; notifyAll(); }
}
class Producer implements Runnable {
private Resourse res; public Producer(Resourse res) { this.res = res; } @Override public void run() { while (true) { res.produce("商品"); } }
}
class Resumer implements Runnable {
private Resourse res; public Resumer(Resourse res) { this.res = res; } @Override public void run() { while (true) { res.resume(); } }
}
“`
相关文章推荐
- java对世界各个时区(TimeZone)的通用转换处理方法(转载)
- java-注解annotation
- java-模拟tomcat服务器
- java-用HttpURLConnection发送Http请求.
- java-WEB中的监听器Lisener
- Android IPC进程间通讯机制
- Android Native 绘图方法
- Android java 与 javascript互访(相互调用)的方法例子
- Python3写爬虫(四)多线程实现数据爬取
- 介绍一款信息管理系统的开源框架---jeecg
- 聚类算法之kmeans算法java版本
- java实现 PageRank算法
- PropertyChangeListener简单理解
- 插入排序
- 冒泡排序
- 堆排序
- 快速排序
- 二叉查找树