zoukankan      html  css  js  c++  java
  • 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();
            }
        }
    
    }

    显示结果:

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

  • 相关阅读:
    webpack学习1-打包
    Cordova开发-2 自定义插件
    Vue项目开发1-项目的创建
    Cordova开发-2 具体插件的使用
    Cordova开发-1 项目的创建
    Mybatis的使用
    XAMPP设置上的问题
    七款Debug工具推荐:iOS
    sqlite内置函数
    CATransition常用动画及type
  • 原文地址:https://www.cnblogs.com/gaoquanquan/p/9912000.html
Copyright © 2011-2022 走看看