下面的代码作用:
开两个线程,一个线程打印数字,一个线程打印字母;
打印结果要求:
12A34B56C.........5152Z
------------------------------------------------------------------------------
public class PrintTest
{
static int printedNum = 1;
static char nextChar = 'A';
static int nextNum = 1;
static Object lock = new Object();
public static void main(String[] args)
{
new Thread(new Runnable()
{
public void run()
{
printChar();
}
public void printChar()
{
synchronized(lock)
{
while(printedNum<79)
{
if((printedNum%3) != 0)
{
try
{
lock.wait();
}
catch(Exception e)
{
e.printStackTrace();
}
}
else
{
System.out.print(nextChar);
printedNum++;
nextChar++;
try
{
lock.notify();
}
catch(Exception e)
{
e.printStackTrace();
}
}
}
}
}
}).start();
new Thread(new Runnable()
{
public void run()
{
printTwoNumber();
}
public void printTwoNumber()
{
synchronized(lock)
{
while(printedNum<79)
{
if((printedNum%3) == 0)
{
try
{
lock.wait();
}
catch(Exception e)
{
e.printStackTrace();
}
}
else
{
for(int i = 0; i < 2; i++)
{
System.out.print(nextNum);
nextNum++;
printedNum++;
}
try
{
lock.notify();
}
catch(Exception e)
{
e.printStackTrace();
}
}
}
}
}
}
).start();
}
}
---------------------------------------------------------------------------------------------------
线程间通讯总结:
1.定义对象锁,通常可以用this,这样不用定义这个对象锁;
若使用类的static成员变量作为对象锁,可以同步所有该类的对象执行同步块的代码;
Object lock = new Object();
2.定义同步语句块,执行之前要先获取对象锁
sychronized(lock)
{
.........
}
3
.阻塞代码所在线程,释放对象锁,交出cpu控制权,转为休眠状态
lock.wait();
4
.唤醒需要lock的所有休眠线程;
lock.notify();
注意:要保证通讯的线程都使用同一个对象锁,否则达不到线程间通讯的目的;
------------------------------------------------------------------------------------------------------------------------------------------------------------
改进后的代码:增加一个类专门处理打印工作,也用它的对象作为对象锁;
总结:一般把同步线程共同用到的数据和操作封装到一个共同的类中,然后由各自的线程类来调用;
public class PrintTest
{
public static void main(String[] args)
{
Printer p = new Printer();
NumThread numThread = new NumThread(p);
CharThread charThread = new CharThread(p);
new Thread(numThread).start();
new Thread(charThread).start();
}
}
class NumThread implements Runnable
{
private Printer p;
public NumThread(Printer p)
{
this.p = p;
}
public void run()
{
p.printNums();
}
}
class CharThread implements Runnable
{
private Printer p;
public CharThread(Printer p)
{
this.p = p;
}
public void run()
{
p.printChar();
}
}
class Printer
{
int printedNum = 1;
char nextChar = 'A';
int nextNum = 1;
public synchronized void printNums()
{
while(printedNum<79)
{
if((printedNum%3) == 0)
{
try
{
wait();
}
catch(Exception e)
{
e.printStackTrace();
}
}
else
{
for(int i = 0; i < 2; i++)
{
System.out.print(nextNum);
nextNum++;
printedNum++;
}
try
{
notify();
}
catch(Exception e)
{
e.printStackTrace();
}
}
}
}
public synchronized void printChar()
{
while(printedNum<79)
{
if((printedNum%3) != 0)
{
try
{
wait();
}
catch(Exception e)
{
e.printStackTrace();
}
}
else
{
System.out.print(nextChar);
printedNum++;
nextChar++;
try
{
notify();
}
catch(Exception e)
{
e.printStackTrace();
}
}
}
}
}