java多线程之类锁
2014-01-04 19:44
218 查看
参考文章:http://blog.csdn.net/ymeng_bupt/article/details/6826936
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------
在java多线程中,如果你在某个类的方法中加了类锁,千万需要注意一个问题:
在唤醒其它线程时,不要用this.notify()或this.notifyAll(),这两个方法用于对象锁,而不是类锁。
---------------------------------------------------------------------------------------------------------------------------------------
开始时,我没有注意以上问题,给方法加了类锁后,直接用this.notifyAll()唤醒其它线程,结果一个
都唤醒不了。加了类锁后,正确的唤醒其它线程的方法是:
类名.class.notifyAll();
如User.class.notifyAll();
-------------------------------------------------------------------------------------------------------------------------------------------------
贴下我加类锁的代码:
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
下面说下我加类锁的原因和用途。
我打算用4个线程模拟桥牌的打牌过程,第一步当然是显示每个线程拥有的牌啦。
我把桥牌的业务功能封装在了一个类中,该类中就有一个输出牌点的功能。
4个线程就有4个该类的对象,如何让这4个线程在输出牌点时输出结果不混乱呢?
这时我用类锁解决了4个线程输出牌点显示混乱的问题。
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
效果截图如下(玩家:北、东、南、西):
---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
主要代码如下:
---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
您的十分满意是我追求的宗旨。
您的一点建议是我后续的动力。
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------
在java多线程中,如果你在某个类的方法中加了类锁,千万需要注意一个问题:
在唤醒其它线程时,不要用this.notify()或this.notifyAll(),这两个方法用于对象锁,而不是类锁。
---------------------------------------------------------------------------------------------------------------------------------------
开始时,我没有注意以上问题,给方法加了类锁后,直接用this.notifyAll()唤醒其它线程,结果一个
都唤醒不了。加了类锁后,正确的唤醒其它线程的方法是:
类名.class.notifyAll();
如User.class.notifyAll();
-------------------------------------------------------------------------------------------------------------------------------------------------
贴下我加类锁的代码:
/** * 加类锁,类名为QiaoPai */ public void AddClassLock() { synchronized(QiaoPai.class) { try { //不满足条件,线程就进入等待状态 if(!nextOne.equals(Thread.currentThread().getName())) { QiaoPai.class.notifyAll();//唤醒所有等待的线程 QiaoPai.class.wait();//进入等待状态 } } catch (Exception e) {e.printStackTrace();} } }
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
下面说下我加类锁的原因和用途。
我打算用4个线程模拟桥牌的打牌过程,第一步当然是显示每个线程拥有的牌啦。
我把桥牌的业务功能封装在了一个类中,该类中就有一个输出牌点的功能。
4个线程就有4个该类的对象,如何让这4个线程在输出牌点时输出结果不混乱呢?
这时我用类锁解决了4个线程输出牌点显示混乱的问题。
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
效果截图如下(玩家:北、东、南、西):
---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
主要代码如下:
import mythread.MyThread; import util.Poker; public class main { /** * @param args */ public static void main(String[] args) { Poker.Shuffle();//洗牌 //创建线程 MyThread threadN=new MyThread(); MyThread threadE=new MyThread(); MyThread threadS=new MyThread(); MyThread threadW=new MyThread(); //发牌 threadN.setPoker(Poker.getPokerN()); threadE.setPoker(Poker.getPokerE()); threadS.setPoker(Poker.getPokerS()); threadW.setPoker(Poker.getPokerW()); //设置线程名字 threadN.setName("N"); threadE.setName("E"); threadS.setName("S"); threadW.setName("W"); //启动线程 threadN.start(); threadE.start(); threadS.start(); threadW.start(); } }
---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
package mythread; import java.lang.Thread; import java.util.List; import business.QiaoPai; //线程类 public class MyThread extends Thread{ QiaoPai qiaoPai=new QiaoPai(); public void run() { try { qiaoPai.ShowPoker(); } catch (Exception e) {e.printStackTrace();} } //设置扑克牌 public void setPoker(List<Integer> poker) { qiaoPai.setPoker(poker); } }
---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
package business;
import java.util.ArrayList;
import java.util.List;
//桥牌业务类
public class QiaoPai {
List<Integer> poker=new ArrayList<Integer>(new Integer(13));//牌
public static String nextOne="N";//下一个玩家
//叫牌
public String JiaoPai(String info)
{
String pai="";
return pai;
}
//获取扑克牌
public List<Integer> getPoker() {
return poker;
}
//设置扑克牌
public void setPoker(List<Integer> poker) {
this.poker = poker;
}
//显示扑克牌
public void ShowPoker()
{
synchronized(QiaoPai.class)
{
AddClassLock();
System.out.print(Thread.currentThread().getName()+":");
for(int i=0;i<poker.size();i++)
{
System.out.print(poker.get(i)+" ");
}
System.out.println();
setNextOne();
DelClassLock();
}
}
/** * 加类锁,类名为QiaoPai */ public void AddClassLock() { synchronized(QiaoPai.class) { try { //不满足条件,线程就进入等待状态 if(!nextOne.equals(Thread.currentThread().getName())) { QiaoPai.class.notifyAll();//唤醒所有等待的线程 QiaoPai.class.wait();//进入等待状态 } } catch (Exception e) {e.printStackTrace();} } }
/**
* 删除类锁,即唤醒所有等待的线程
*/
public void DelClassLock()
{
synchronized(QiaoPai.class)
{
try{
QiaoPai.class.notifyAll();
}
catch (Exception e) {e.printStackTrace();}
}
}
/**
* 设置下一位玩家
*/
public static void setNextOne()
{
if(nextOne.equals("N"))
{
nextOne="E";
}
else if(nextOne.equals("E"))
{
nextOne="S";
}
else if(nextOne.equals("S"))
{
nextOne="W";
}
else if(nextOne.equals("W"))
{
nextOne="N";
}
else
{
}
}
}
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
您的十分满意是我追求的宗旨。
您的一点建议是我后续的动力。
相关文章推荐
- java多线程 基础(二) Thread Runnable
- 黑马程序员_java入门_多线程
- JNI 使用多线程回调java 方法
- Java多线程编程核心技术---线程间通信(二)
- Java多线程-线程状态及方法的使用
- Java 多线程(PART IX) synchronized(II) 对对象进行加锁
- java学习日记(6)____多线程的安全问题与死锁的产生
- java 多线程 - 饱和策略(转 Sun官方论坛)
- java中的多线程
- Java学习笔记―第十一章 多线程机制
- Java多线程数据隔离(ThreadLocal)
- 【Todo】【读书笔记】Java多线程编程指南-设计模式篇
- Java多线程
- 第九章 Java多线程机制 03_Join_Yield_Priority
- (7)Java多线程
- Java中的多线程
- java多线程细节
- Java 7之多线程线程池 - 线程池原理(2)
- Java多线程基础一(基础概念)
- 编写多线程java程序时需要注意哪些问题?(来自于effective java se)