javaマルチスレッド小記

34246 ワード

javaマルチスレッド小記
  • Thread類
  • を継承する。
  • Runnableインターフェース
  • を実現する。
  • 従来の方法は
  • を実現する。
  • は、匿名の内部クラスによって
  • を実現する。
  • は、Lamata表現により
  • を実現する。
  • Callableインターフェース
  • を実現します。
  • スレッドの5大状態
  • マルチスレッドのチケット購入例
  • 本論文の参考https://blog.csdn.net/HeZhiYing_/アート/detail/10943962
    Thread類を継承する
    Thread類を継承して、run方法を書き直すということです。Javaは単独で継承されているので、この方法は少ないです。一般的にはRunnableインターフェースを使います。
    public class testxc {
    
        @Test
        public void testThread(){
            new MyThread().start();
        }
    }
    
    
    public class MyThread extends Thread{
        @Override
        public void run(){
            for (int i = 0; i < 10; i++) {
                System.out.println(Thread.currentThread().getName()+":"+i);
            }
        }
    }
    
    Runnableインターフェースを実現
    従来の方法で実現する
    @Test
        public void  testRunnable(){
            new Thread(new MyThread()).start();
            new Thread(new MyThread(),"     ").start();
        }
    
    public class MyThreadRun implements Runnable {
        @Override
        public void run() {
            for (int i = 0; i < 100; i++) {
                System.out.println(Thread.currentThread().getName()+":"+i);
            }
        }
    }
    
    匿名の内部クラスで実現
     @Test
        public  void  testRunnable1(){
            new Thread(new Runnable() {
                @Override
                public void run() {
                    for (int i = 0; i < 100; i++) {
                        System.out.println(Thread.currentThread().getName() + ":" + i);
                    }
                }
            }).start();
        }
    
    Lamata表現で実現
        @Test
        public  void  testRunnable2(){
            new Thread(()->{
                for (int i = 0; i < 100; i++) {
                    System.out.println(Thread.currentThread().getName() + ":" + i);
                }
            }).start();
        }
    
    Callableインターフェースを実現
    	@Test
        public void testCallable() throws ExecutionException, InterruptedException {
            //       
            ExecutorService service = Executors.newFixedThreadPool(3);
            //     
            Future<Boolean> future1 = service.submit(new MyThread());
            Future<Boolean> future2 = service.submit(new MyThread());
            Future<Boolean> future3 = service.submit(new MyThread());
            //      
            Boolean b1 = future1.get();
            Boolean b2 = future2.get();
            Boolean b3 = future3.get();
    
    
            System.out.println(b1);
            System.out.println(b2);
            System.out.println(b3);
            //     
            service.shutdown();
        }
    
     	public class MyThread implements Callable<Boolean> {
        @Override
        public Boolean call() throws Exception {
            for (int i = 0; i < 100; i++) {
                System.out.println(Thread.currentThread().getName() + ":" + i);
            }
            return true;
        }
    }
    
    
    スレッドの五大状態
        
    	       ,      new Thread();
        
    	       ,    myThread.start();
        
    	             。
        
    	     (wait)、  (synchronized)、sleep join   
        
    	run()  、main()  
          :
    	setPriority(int new Priority)        
    	sleep(long millis)         
    	join()     ,          ,         。
    	yield()    ,       ,              
    	interrupt()    (    )
    	isAlive()            
    
    マルチスレッドのチケット購入例
    public class testxc {
        @Test
        public void trick(){
            MyThread myThread = new MyThread();
            new Thread(myThread,"  1").start();
            new Thread(myThread,"  2").start();
            new Thread(myThread,"  3").start();
            new Thread(myThread,"  4").start();
            new Thread(myThread,"  5").start();
        }
    }
    
    
    public class MyThread implements Runnable {
        private int ticket = 100;
        private boolean flag = true;
        @Override
        public void run() {
            while (flag) {
                System.out.println(flag+":"+ticket--);
                buy();
            }
        }
        public void buy() {
            if (ticket <= 0) {
                flag = false;
                return;
            }
            try {
                Thread.sleep(100);//       100ms
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println(Thread.currentThread().getName() + ":"+ ticket--);
        }
    }
    
    
    スレッドの安全問題が発生したのは、ticketが0になる前に、複数のスレッドが同時に入ってきたからです。解決方法は、synchronizedスレッドを同期させることにより、同期方法と同期コードブロックを用いて解決することができる。同期方法とは、方法にsynchronizedキーワードを付加することです。
    public class Main {
        public static void main(String[] args){
            MyThread myThread = new MyThread();
            new Thread(myThread,"  1").start();
            new Thread(myThread,"  2").start();
            new Thread(myThread,"  3").start();
        }
    }
    
    class MyTicket {
        int ticket;
    
        public MyTicket(int ticket) {
            this.ticket = ticket;
        }
    }
    
    class MyThread implements Runnable {
        MyTicket myTicket = new MyTicket(100);
        private boolean flag = true;
        @Override
        public void run() {
            while (flag) {
                buy();
            }
        }
        public void buy() {
            synchronized (myTicket) {
                if (myTicket.ticket <= 0) {
                    flag = false;
                    return;
                }
                try {
                    Thread.sleep(100);//       100ms
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println(Thread.currentThread().getName() + ":"+ myTicket.ticket--);
            }
    
        }
    }
    
    です。