线程的notify:
1)要在synchronized代码块或方法里使用
2)唤醒在同一个监视器(synchronized)上的等待线程,如果不止一个线程在此同步监视器等待,则根据调度对策选择唤醒其中一个。只有当前线程放弃对当前同步监视器的锁定后才能执行被唤醒的线程。
线程的wait:
1)要在synchronized代码块或者方法里使用
2)导致当前线程等待,直到其他线程调用该同步监视器的notify()或者notifyAll()方法。
3)wait有三种方法重载。
身为一个小白,最近在学习线程,使用的教材书是《疯狂JAVA讲义》,在做书上课后习题时对wait和notify函数的使用有了进一步,特意写下笔记,小小拙见,如果有什么不对欢迎补充。
首先,需要了解synchronized,一个线程执行同步代码块时,首先要得到对同步监视器的锁定。
整个流程就是“锁定-执行-解锁(释放锁)”
书上的简单问题
一个错误例子:
public class Test_1
{
public static void main(String args[ ])
{
WriteWordThread zhang,wang;
zhang=new WriteWordThread("张小红"); //新建线程。
wang=new WriteWordThread("JamsKeven"); //新建线程。
zhang.start(); //启动线程。
wang.start(); //启动线程
for(int i=1;i<=8;i++)
{
System.out.println("我是主线程中的语句"+Thread.currentThread().getName());
}
System.out.println("done");
}
}
class WriteWordThread extends Thread
{
tt test;
WriteWordThread()
{
test = new tt();
}
WriteWordThread(String s)
{
setName(s); //调用Thread类的方法setName为线程起个名字。
}
public synchronized void run()
{
//System.out.println(Thread.currentThread().getName());
//test.ttt(Thread.currentThread().getName());
int n = 0;
if(Thread.currentThread().getName().equals("张小红")){
try{
for(int i = 1; i <= 52; ++i){
System.out.print(i);
++n;
if(n%2==0){
notify();
wait();
}
}
}catch(Exception e){System.out.println("1 "+e.toString());}
}
else{
try{
Thread.sleep(10);//为了让数字先打印
for(char i = 'A'; (int)i <= (int)'Z'; ++i){
System.out.print(i);
if((int)i < (int)'Z')
{
notify();
wait();
}
}
notify();//字母打印完后,唤醒等待的数字线程
}catch(InterruptedException e){System.out.println(e.toString());}
}
}
}
这个错误的例子犯的错误就是不是同一个监视器,所以两个线程执行一次后就一直处于等待中,没有线程唤醒它。
正确的例子(也有更加简单的写法)
public class Test_1
{
public static void main(String args[ ])
{
WriteWordThread all =new WriteWordThread();
//WriteWordThread zhang,wang;
Thread zhang=new Thread(all); //新建线程。
Thread wang=new Thread(all); //新建线程。
zhang.setName("张小红");
wang.setName("JamsKeven");
//zhang=new WriteWordThread("张小红"); //新建线程。
//wang=new WriteWordThread("JamsKeven"); //新建线程。
zhang.start(); //启动线程。
wang.start(); //启动线程
for(int i=1;i<=8;i++)
{
System.out.println("我是主线程中的语句"+Thread.currentThread().getName());
}
System.out.println("done");
}
}
class WriteWordThread extends Thread
{
WriteWordThread()
{
}
WriteWordThread(String s)
{
setName(s); //调用Thread类的方法setName为线程起个名字。
}
public void set(String s){
setName(s);
}
public synchronized void run()
{
int n = 0;
if(Thread.currentThread().getName().equals("张小红")){
try{
for(int i = 1; i <= 52; ++i){
System.out.print(i);
++n;
if(n%2==0){
notify();
wait();
}
}
}catch(Exception e){System.out.println("1 "+e.toString());}
}
else{
try{
Thread.sleep(10);
for(char i = 'A'; (int)i <= (int)'Z'; ++i){
System.out.print(i);
if((int)i < (int)'Z')
{
notify();
wait();
}
}
notify();
}catch(InterruptedException e){System.out.println(e.toString());}
}
}
}