多线程知识点

题目:

请编写一个多线程程序,实现两个线程,其中一个线程完成对某个对象的int类型成员变量的增加操作,即每次加1;另一个线程完成对成员变量的减小操作,即每次减1,同时保证该变量的值不会小于0,不会大于1,该变量的初始值为0。

包含int类型成员变量的类:

public class Test {

    // int类型成员变量
    private int num;
    
    // 增加
    public synchronized void increase() {
        if(num != 0) {
            try {
                wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        num ++;
        System.out.println("increase :" + num);
        notify();
    }
    
    // 减小
    public synchronized void decrease() {
        if(num == 0) {
            try {
                wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        num --;
        System.out.println("decrease :" + num);
        notify(); 
    }
}
View Code

增加成员变量的线程:

/**
 * 增加线程,直接继承自Thread,也可实现Runnable接口
 * @author Wu
 *
 */
public class IncreaseThread extends Thread{

    private Test test;
    
    public IncreaseThread(Test test) {
        this.test = test;
    }
    
    @Override
    public void run() {
        for(int i = 0; i < 10; i ++) {
            test.increase();
        }
    }
}
View Code

减少成员变量的线程:

/**
 * 减少线程,直接继承自Thread,也可实现Runnable接口
 * @author Wu
 *
 */
public class DecreaseThread extends Thread{

    private Test test;
    
    public DecreaseThread(Test test) {
        this.test = test;
    }
    
    @Override
    public void run() {
        for(int i = 0; i < 10; i ++) {
            test.decrease();
        }
    }
    
}
View Code

测试程序:

      
class Main {      
    public static void main(String[] args) {      
        Test test = new Test();
        
        Thread t1 = new IncreaseThread(test);
        Thread t2 = new DecreaseThread(test);
        
        t1.start();
        t2.start();
        
        
    }
}      
View Code

测试结果

increase :1
decrease :0
increase :1
decrease :0
increase :1
decrease :0
increase :1
decrease :0
increase :1
decrease :0
increase :1
decrease :0
increase :1
decrease :0
increase :1
decrease :0
increase :1
decrease :0
increase :1
decrease :0
View Code

总结

一、关于wait,notify,notifyAll以及sleep方法的关系。

1、如果一个线程调用了某个对象的wait方法,那么该线程首先必须要拥有该对象的锁(换句话说,一个线程如果调用了某个对象的wait,那么该wait方法必须要在synchronized中)。

2、如果一个线程调用了某个对象的wait方法,那么该线程就会释放该对象的锁。

3、在Java对象中,有两种池(锁池、等待池)。

4、如果一个线程调用了某个对象的wait方法,那么该线程进入该对象的等待池中(释放锁),如果未来某个时刻,另外一个线程调用了相同的对象的notify或者notifyAll方法,那么在该等待池中的等待的线程就会起来进入该对象的 锁池中,去等待获得该对象的锁,如果获得锁成功,那么该线程将继续沿着wait方法之后的路径去执行。

5、如果一个线程调用了sleep方法睡眠,那么在睡眠的同时,它不会失去对象的锁的拥有权。

二、关于synchronized关键字的作用。

1、在某个对象的所有synchronized方法中,在某一时刻,只能有一个唯一的线程去访问这些synchronized方法。

/**
 * 线程t1先执行,即使睡了2秒钟,线程t2也必须等待t1释放锁,才能访问test对象的synchronized方法     
 * @author Wu
 *
 */
class Main {      
    public static void main(String[] args) {      
        Test test = new Test();
        Thread t1 = new Thread(new Thread1(test));
        Thread t2 = new Thread(new Thread2(test));
        
        t1.start();
        t2.start();
        
    }
}     
class Thread1 implements Runnable {
    Test test;
    public Thread1(Test test) {
        this.test = test;
    }
    @Override
    public void run() {
        test.hello();
    }
    
}

class Thread2 implements Runnable {
    Test test;
    public Thread2(Test test) {
        this.test = test;
    }
    @Override
    public void run() {
        test.world();
    }
    
}
class Test {
    public synchronized void hello() {
        try {
            Thread.sleep(2000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("hello");
    }
    
    public synchronized void world() {
        System.out.println("world");
    }
}
View Code

2、如果有一个方法时synchronized方法,那么该synchronized关键字表示给当前对象上锁。

3、如果一个synchronized方法是静态的,那么该synchronized关键字表示给当前对象所对应的Class对象上锁(每个类不管生成多少个对象,其对应的Class对象只有一个)。


class Main {      
    public static void main(String[] args) {      
        Test test1 = new Test();
        Thread t1 = new Thread(new Thread1(test1));
        Test test2 = new Test();
        Thread t2 = new Thread(new Thread2(test2));
        
        t1.start();
        t2.start();
        
    }
}     
class Thread1 implements Runnable {
    Test test;
    public Thread1(Test test) {
        this.test = test;
    }
    @Override
    public void run() {
        test.hello();
    }
    
}

class Thread2 implements Runnable {
    Test test;
    public Thread2(Test test) {
        this.test = test;
    }
    @Override
    public void run() {
        test.world();
    }
    
}
class Test {
    public static synchronized void hello() {
        try {
            Thread.sleep(5000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("hello");
    }
    
    public static synchronized void world() {
        System.out.println("world");
    }
}
View Code

posted @ 2016-08-24 10:38  no_one  阅读(278)  评论(0)    收藏  举报