-------------------------------------------------------------------------------------------------------------------------------------------------------------------------

在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个线程输出牌点显示混乱的问题。

--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

效果截图如下(玩家:北、东、南、西):

java多线程之类锁_synchronized

---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

主要代码如下:


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
{

}
}
}


----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------


​​

您的十分满意是我追求的宗旨。

您的一点建议是我后续的动力。