Java中的多线程(同步线程)

public class test{
    public static void main(String[] args) throws IOException{
        Thread1 t1 = new Thread1("A");
        Thread1 t2 = new Thread1("B");
        Thread1 t3 = new Thread1("C");
        t1.start();
        t2.start();
        t3.start();        
    }
}
class Thread1 extends Thread{
private static int num = 50;
public Thread1(String string){
    super(string);
}
@Override
public void run(){
    for(int i=0;i<50;i++){
        try {
	    sleep(10);
	} catch (InterruptedException e) {
	    e.printStackTrace();
	}    
        if(num>0){
            System.out.println(this.currentThread().getName()+">>>>>"+(--num));
        }                                                                            
    }
}
}
C>>>>>48
A>>>>>48//出现重复数字
B>>>>>49
A>>>>>47
B>>>>>47
C>>>>>46
B>>>>>45
C>>>>>44
A>>>>>45
B>>>>>42
C>>>>>42
A>>>>>43
C>>>>>41
B>>>>>41
A>>>>>41
B>>>>>40
C>>>>>40
A>>>>>40
B>>>>>39
A>>>>>39
C>>>>>39
A>>>>>38
B>>>>>38
C>>>>>38
C>>>>>37
B>>>>>36
A>>>>>37
A>>>>>35
C>>>>>33
B>>>>>34
C>>>>>32
A>>>>>31
B>>>>>30
C>>>>>29
A>>>>>29
B>>>>>29
A>>>>>28
C>>>>>28
B>>>>>27
C>>>>>26
A>>>>>26
B>>>>>26
A>>>>>25
C>>>>>24
B>>>>>25
B>>>>>23
C>>>>>22
A>>>>>23
C>>>>>21
A>>>>>21
B>>>>>20
C>>>>>19
A>>>>>19
B>>>>>19
B>>>>>18
A>>>>>17
C>>>>>16
C>>>>>15
B>>>>>13
A>>>>>14
C>>>>>12
A>>>>>11
B>>>>>12
A>>>>>10
C>>>>>10
B>>>>>10
A>>>>>9
C>>>>>8
B>>>>>8
B>>>>>7
A>>>>>5
C>>>>>6
A>>>>>4
B>>>>>4
C>>>>>4
B>>>>>2
C>>>>>1
A>>>>>3
A>>>>>0
C>>>>>-1//出现负数
B>>>>>0

原因:当两个线程同时进入到if(num>0)的代码块中,一个线程开始执行输出语句,但还没执行到--num,另一条线程也开始执行打印操作,就会打印相同的数字。同样,当一条线程执行完--num且num=0,就会出现另一条线程执行完--num出现的是-1。

解决办法:

  • 使用同步代码块
public void run(){
    for(int i=0;i<50;i++){
        //使用同步代码块
        synchronized(this.getClass()){
            if(num>0){
                ···
            }        
        }
    }
}

语法:

synchronized(同步锁){
    //需要同步操作的代码(最多只有一个线程能够拿到同步锁,拿到同步锁之后该线程才能进入代码块)
}
  • 使用同步方法

使用synchronized关键字来修饰方法

@Override
public void run(){
    for(int i=0;i<50;i++){
        sell();
    }
}
private synchronized void sell(){
    if(num>0){
        ···    
    }
}

注意:不能用synchronized来修饰run()方法,不然只能有一个线程进去执行完所有的操作。

  • 使用锁机制
public class test{
    public static void main(String[] args) throws IOException{
        Lock l = new ReentrantLock();
	Thread1 t1 = new Thread1("A",l);
	Thread1 t2 = new Thread1("B",l);
	Thread1 t3 = new Thread1("C",l);
	t1.start();
	t2.start();
	t3.start(); 
    }
}
class Thread1 extends Thread{
        String name;
	Lock lock;
	private static int num = 50;
	public Thread1(String string,Lock lock) {
		this.name = string;
		this.lock = lock;
	}
	@Override
	public void run(){
		for(int i=0;i<50;i++){
			lock.lock();
			try {
			    if(num>0){
			    sleep(10);
			    System.out.println(this.currentThread().getName()+">>>>>"+(--num));
			}
			} catch (InterruptedException e) {
				e.printStackTrace();
			} finally{
				lock.unlock();
			}
		}
	}
}
注意:要把锁作为参数给每一个线程。



猜你喜欢

转载自blog.csdn.net/edison_style/article/details/80566909