理解高并发(3).多线程开发常见问题示例
2017-07-24 12:32
295 查看
多线程开发过程中,经常会出现的一些问题:非线程安全、死锁、饥饿锁。 示例代码如下:
非线程安全
package com.zuche.thread.demo1;
public class TestClient {
public static void main(String[] args) {
final Account account = new Account(1000);
Thread t = new Thread(new Runnable(){
public void run() {
account.add(20);
}
});
Thread t1 = new Thread(new Runnable(){
public void run() {
account.withdraw(20);
}
});
t.start();
t1.start();
System.out.println("最后的金额:" + account.getBalance());
}
}
理论上最后的金额应该为1000
死锁
package com.zuche.thread.demo3;
public class WorkThread extends Thread{
private String adjustMoney = "adjustMoney";
private String work = "work";
private String ruleType;
public WorkThread(String ruleType){
this.ruleType = ruleType;
}
public void run(){
if(ruleType.equals("employee")){
employeeSay();
}
if(ruleType.equals("boss")){
bossSay();
}
}
private void employeeSay(){
synchronized(adjustMoney){
System.out.println("员工说,先调薪后干活");
synchronized (work) {
System.out.println("员工调薪顺利调薪,开始带劲的干活");
}
}
}
private void bossSay(){
synchronized(work){
System.out.println("老板说,先给我好好的干活再来谈加薪的事儿");
synchronized(adjustMoney){
System.out.println("活干的不错,可以适当的考虑加点钱");
}
}
}
}
运行后,程序不能正常退出,卡死在那儿。
死锁概念: 2个线程相互僵持不下,导致无法访问共享资源,最终无法释放锁资源。
饥饿锁
package com.zuche.thread.demo2;
public class Toilet{
public synchronized void doStaff(){
System.out.println(Thread.currentThread().getName() + " begin.");
clean();
while(true){
System.out.println(Thread.currentThread().getName() + " doing.");
try {
Thread.sleep(2000L);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
private void clean(){
}
}
运行后,另一个线程无法访问共享资源
饥饿锁概念: 一个线程占用着锁不放导致其它线程无法访问共享资源
非线程安全
package com.zuche.thread.demo1;
public class TestClient {
public static void main(String[] args) {
final Account account = new Account(1000);
Thread t = new Thread(new Runnable(){
public void run() {
account.add(20);
}
});
Thread t1 = new Thread(new Runnable(){
public void run() {
account.withdraw(20);
}
});
t.start();
t1.start();
System.out.println("最后的金额:" + account.getBalance());
}
}
理论上最后的金额应该为1000
死锁
package com.zuche.thread.demo3;
public class WorkThread extends Thread{
private String adjustMoney = "adjustMoney";
private String work = "work";
private String ruleType;
public WorkThread(String ruleType){
this.ruleType = ruleType;
}
public void run(){
if(ruleType.equals("employee")){
employeeSay();
}
if(ruleType.equals("boss")){
bossSay();
}
}
private void employeeSay(){
synchronized(adjustMoney){
System.out.println("员工说,先调薪后干活");
synchronized (work) {
System.out.println("员工调薪顺利调薪,开始带劲的干活");
}
}
}
private void bossSay(){
synchronized(work){
System.out.println("老板说,先给我好好的干活再来谈加薪的事儿");
synchronized(adjustMoney){
System.out.println("活干的不错,可以适当的考虑加点钱");
}
}
}
}
运行后,程序不能正常退出,卡死在那儿。
死锁概念: 2个线程相互僵持不下,导致无法访问共享资源,最终无法释放锁资源。
饥饿锁
package com.zuche.thread.demo2;
public class Toilet{
public synchronized void doStaff(){
System.out.println(Thread.currentThread().getName() + " begin.");
clean();
while(true){
System.out.println(Thread.currentThread().getName() + " doing.");
try {
Thread.sleep(2000L);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
private void clean(){
}
}
运行后,另一个线程无法访问共享资源
饥饿锁概念: 一个线程占用着锁不放导致其它线程无法访问共享资源
相关文章推荐
- 并发危险:解决多线程代码中的 11 个常见的问题(C#示例) from MSDN
- 【转】并发危险:解决多线程代码中的 11 个常见的问题
- [Android开发常见问题-7] 多线程开发的几种方式和子线程操作UI线程控件的问题
- HashMap源码和常见问题分析以及多线程开发时的问题
- 多线程并发常见问题
- 多线程并发常见问题
- 基于多线程并发的常见问题(详解)
- 并发危险-解决多线程代码中的11个常见的问题
- 并发危险:解决多线程代码中的11个常见问题
- 多线程并发常见问题
- 游戏开发中的常见问题:并发
- 并发危险-解决多线程代码中的11个常见的问题
- Java多线程并发开发之DelayQueue使用示例
- 并发危险:解决多线程代码中的 11 个常见的问题
- [Android开发常见问题-23] Android Handler、Message完全解析,带你从源码的角度彻底理解
- ASP.Net开发常见问题
- ASP.Net开发新手常见问题备忘录
- Asp及Web开发中的常见问题
- DELPHI开发Web程序常见问题
- Linux KDevelop开发常见问题