java——多线程的实现方式、三种办法解决线程赛跑、多线程数据同步(synchronized)、死锁

多线程的实现方式:demo1、demo2

demo1:继承Thread类,重写run()方法

package thread_test;

public class ThreadDemo1 extends Thread {
    ThreadDemo1(){
        
    }
    ThreadDemo1(String szName){
        super(szName);
    }
    
    //重载run函数
    public void run() {
        for(int count = 1 , row = 1 ; row < 10 ; row ++ , count ++) {
            for(int i = 0 ; i < count ; i ++) {
                System.out.print("*");
            }
            System.out.println();
        }
    }
    
    public static void main(String[] args) {
        //线程赛跑
        ThreadDemo1 td1 = new ThreadDemo1();
        ThreadDemo1 td2 = new ThreadDemo1();
        ThreadDemo1 td3 = new ThreadDemo1();
        td1.start();
        td2.start();
        td3.start();
    }

}

demo2:实现runnable接口,实现run()方法

package thread_test;

public class ThreadDemo2 implements Runnable{

    public void run() {
        for(int count = 1 , row = 1 ; row < 10 ; row ++ , count ++) {
            for(int i = 0 ; i < count ; i ++) {
                System.out.print("*");
            }
            System.out.println();
        }
    }
    
    public static void main(String[] args) {
        //存在线程赛跑问题
        Runnable rb1 = new ThreadDemo2();
        Runnable rb2 = new ThreadDemo2();
        Runnable rb3 = new ThreadDemo2();
        Thread td1 = new Thread(rb1);
        Thread td2 = new Thread(rb2);
        Thread td3 = new Thread(rb3);
        td1.start();
        td2.start();
        td3.start();
    }
}

demo3:两种方法解决进程赛跑问题

package thread_test;

//两种方法解决线程赛跑
class ThreadWait extends Thread{

    public ThreadWait() {
        
    }
    
    public ThreadWait(String name) {
        super(name);
    }
    
    @Override
    public void run() {
        for(int count = 1 , row = 1 ; row < 10 ; row ++ , count ++) {
            for(int i = 0 ; i < count ; i ++) {
                System.out.print("*");
            }
            System.out.println();
        }
    }
}

public class ThreadDemo3{
    public static void main(String[] args) {
        ThreadDemo3 td = new ThreadDemo3();
//        td.Method1();
        td.Method2();
    }
    
    public void Method1() {
        ThreadWait tw1 = new ThreadWait();
        ThreadWait tw2 = new ThreadWait();
        tw1.start();
        while(tw1.isAlive()) {
            try{
                Thread.sleep(100);
            }catch(Exception e){
                e.getMessage();
            }
        }
        tw2.start();
    }
    
    public void Method2() {
        ThreadWait tw1 = new ThreadWait();
        ThreadWait tw2 = new ThreadWait();
        tw1.start();
        try {
            tw1.join(); // 等待该线程中止
        }catch(Exception e){
            e.toString();
        }
        tw2.start();
    }
}

线程异步访问数据导致问题:

package thread_test;

//线程异步访问数据导致问题
class ShareData{
    public static String szData = "";
}

class ThreadDemo extends Thread{
    
    private static ShareData oShare;
    
    ThreadDemo(){
    }
    
    ThreadDemo(String name, ShareData oShare){
        super(name);
        this.oShare = oShare;
    }
    
    public void run() {
        for(int i = 0 ; i < 5 ; i ++) {
            if(this.getName().equals("th1")) {
                oShare.szData = "这是第一个进程";
                try {
                    Thread.sleep(100);
                }catch(Exception e) {
                    
                }
                System.out.println(this.getName() + oShare.szData);
            }else if(this.getName().equals("th2")) {
                oShare.szData = "这是第二个进程";
                try {
                    Thread.sleep(100);
                }catch(Exception e) {
                    
                }
                System.out.println(this.getName() + oShare.szData);
            }
        }
    }
}

 public class ThreadDemo5 {

    public static void main(String[] args) {
        ShareData oShare = new ShareData();
        ThreadDemo th1 = new ThreadDemo("th1", oShare);
        ThreadDemo th2 = new ThreadDemo("th2", oShare);
        th1.start();
        th2.start();
    }
}

得到的结果并不是我们想要的:

解决办法:

  通过“锁”解决线程赛跑问题并实现多线程数据同步:

package thread_test;
class ShareData0{ public static String szData = ""; } class ThreadDemo0 extends Thread{ private static ShareData0 oShare; ThreadDemo0(){ } ThreadDemo0(String name, ShareData0 oShare){ super(name); this.oShare = oShare; } public void run() { //同步快,并指出同步数据oShare synchronized(oShare){ for(int i = 0 ; i < 5 ; i ++) { if(this.getName().equals("th1")) { oShare.szData = "这是第一个进程"; try { Thread.sleep(100); }catch(Exception e) { } System.out.println(this.getName() + oShare.szData); }else if(this.getName().equals("th2")) { oShare.szData = "这是第二个进程"; try { Thread.sleep(100); }catch(Exception e) { } System.out.println(this.getName() + oShare.szData); } } } } } public class ThreadDemo6 { public static void main(String[] args) { ShareData0 oShare = new ShareData0(); ThreadDemo0 th1 = new ThreadDemo0("th1", oShare); ThreadDemo0 th2 = new ThreadDemo0("th2", oShare); th1.start(); th2.start(); } }

得到结果:

死锁:由于两个线程都在等待对方释放各自拥有的锁的现象称为死锁,这种现象往往是由于相互潜逃的synchronized代码段而造成的,所以少用synchronized嵌套。

下面是一个死锁的例子:

package thread_test;

public class LockedThread extends Thread{
    
    private static Object A = new Object();
    private static Object B = new Object();
    private static boolean flag = true;
    
    public static void main(String[] args) {
        LockedThread th1 = new LockedThread();
        LockedThread th2 = new LockedThread();
        
        th1.start();
        th2.start();
    }
    
    public void AccessA() {
        flag = false;
        synchronized(A) {
            System.out.println("th1获得了A的锁");
            try {
                Thread.sleep(1000);
            }catch(Exception e) {
                
            }
            System.out.println("th1还想要B的锁");
            synchronized(B) {
                System.out.println("th1获得了B的锁");
            }
        }
    }
    
    public void AccessB() {
        flag = true;
        synchronized(B) {
            System.out.println("th2获得了B的锁");
            try {
                Thread.sleep(1000);
            }catch(Exception e) {
                
            }
            System.out.println("th2还想要A的锁");
            synchronized(A) {
                System.out.println("th2获得了A的锁");
            }
        }
    }
    
    public void run(){
        if(flag) {
            AccessA();
        }else {
            AccessB();
        }
    }

}

显示结果:

程序没有结束 而是停在了这里,这就是死锁。

 

posted @ 2018-11-05 22:28  高圈圈  阅读(1040)  评论(0编辑  收藏  举报