zoukankan      html  css  js  c++  java
  • Java Thread part 1

    package threadtest;
    
    /** 
     * 事实上,Runnable类称作Task更加确切
     * 真正的线程是执行单位,应该是Thread或Executor 
     */
    public class TestThread extends Thread {
        private static int id = 1;
    
        @Override
        public void run() {
            System.out.println(this + " id: " + id++);
        }
    }
    
    package threadtest;
    
    import java.util.concurrent.ExecutorService;
    import java.util.concurrent.Executors;
    
    public class Executor {
        public static void main(String[] args) {
            // 创建一个可根据需要创建新线程的线程池,但是在以前构造的线程可用时将重用它们
            // 它通常会创建与所需数量相同的线程,然后在回收旧线程时停止创建新线程
            ExecutorService executor = Executors.newCachedThreadPool();
            
            // 创建一个可重用固定线程集合的线程池,以共享的无界队列方式来运行这些线程
            // 一般来讲只有当 cachedThreadPool 会引发问题时才需要使用它
            // ExecutorService executor = Executors.newFixedThreadPool(3);
            
            // 相当与使用 newFixedThreadPool(1)
            // 可以知道当线程数只有1的时候,所有的任务将会是顺序执行,而不能并发
            // ExecutorService executor = Executors.newSingleThreadExecutor();
            
            // 执行线程 
            for (int i = 0; i < 5; i++)
                executor.execute(new TestThread());
            
            // 启动一次顺序关闭,执行以前提交的任务,但不接受新任务。如果已经关闭,则调用没有其他作用 
            executor.shutdown();
        }
    }

    Thread[Thread-0,5,main] id: 1
    Thread[Thread-2,5,main] id: 2
    Thread[Thread-1,5,main] id: 3
    Thread[Thread-4,5,main] id: 4
    Thread[Thread-3,5,main] id: 5

    Callable接口,作用是可以使用ExecutorService.submit()方法执行Callable线程,并获得线程的执行结果

    package threadtest;
    
    import java.util.concurrent.Callable;
    
    /**
     * 线程返回值,使用Callable接口实现
     */
    public class CallThread implements Callable<String> {
    
        @Override
        public String call() throws Exception {
            return this + " Result: This is a thread callback result!";
        }
    
    }
    
    package threadtest;
    
    import java.util.ArrayList;
    import java.util.List;
    import java.util.concurrent.ExecutionException;
    import java.util.concurrent.ExecutorService;
    import java.util.concurrent.Executors;
    import java.util.concurrent.Future;
    
    public class CallTest {
        public static void main(String[] args) {
            ExecutorService executor = Executors.newCachedThreadPool();
            
            // 使用一个 ArrayList 存储 Callable 的回调结果
            List<Future<String>> results = new ArrayList<Future<String>>();
            
            // 使用 executor 的submit() 方法获取回调结果,结果类型是 Future 
            for (int i = 0; i < 5; i++)
                results.add(executor.submit(new CallThread()));
            
            executor.shutdown();
            
            for (Future<String> f : results) {
                try {
                    // Future 的 get() 方法可以获取 Callable 的 call() 方法结果 
                    System.out.println(f.get());
                } catch (InterruptedException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                } catch (ExecutionException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
        }
    }

    threadtest.CallThread@a87e7b Result: This is a thread callback result!
    threadtest.CallThread@11be57f Result: This is a thread callback result!
    threadtest.CallThread@780af5 Result: This is a thread callback result!
    threadtest.CallThread@11775bc Result: This is a thread callback result!
    threadtest.CallThread@132a4df Result: This is a thread callback result!

    线程优先级的示范,线程优先级越高,则执行的顺序越靠前

    package threadtest;
    
    public class PriorityThread extends Thread {
        private int priority;
        private volatile double d;
        
        public PriorityThread(int priority) {
            this.priority = priority;
        }
    
        @Override
        public void run() {
            // setPriority() 应该在 run() 方法的开头写上 
            Thread.currentThread().setPriority(priority);
            for (int i = 0; i < 10000000; i++) {
                d += (Math.PI + Math.E) / (double) i;
                if (i % 1000 == 0)
                    Thread.yield();
            }
            System.out.println(Thread.currentThread() + "|" + this);
        }
    }
    
    package threadtest;
    
    import java.util.concurrent.ExecutorService;
    import java.util.concurrent.Executors;
    
    public class PriorityTest {
        public static void main(String[] args) {
            // 需要注意,使用 ExecutorService 来管理线程
            // Thread.currentThread() 和 this 是不一样的
            // 所以应该尽量使用 Thread.currentThread() 避免这个问题发生
            ExecutorService exec = Executors.newCachedThreadPool();
            for (int i = 0; i < 4; i++) {
                exec.execute(new PriorityThread(Thread.MIN_PRIORITY));
            }
            exec.execute(new PriorityThread(Thread.MAX_PRIORITY));
            
            // 测试 currentThread() 和 this 的区别,此处使用start是一样的 
            (new PriorityThread(1)).start();
            exec.shutdown();
        }
    }

    Thread[Thread-5,1,main]|Thread[Thread-5,1,main]
    Thread[pool-1-thread-5,10,main]|Thread[Thread-4,5,main]
    Thread[pool-1-thread-2,1,main]|Thread[Thread-1,5,main]
    Thread[pool-1-thread-1,1,main]|Thread[Thread-0,5,main]
    Thread[pool-1-thread-4,1,main]|Thread[Thread-3,5,main]
    Thread[pool-1-thread-3,1,main]|Thread[Thread-2,5,main]

    Thread.join(threadA)方法的使用,它的作用是在线程A执行过程中挂起,让线程B执行,直到B被interrupt或者执行完毕

    package threadtest;
    
    import java.util.concurrent.ExecutorService;
    import java.util.concurrent.Executors;
    import java.util.concurrent.TimeUnit;
    
    public class SleepTask extends Thread {
        private String name;
        
        public SleepTask(String name) {
            this.name = name;
        }
        
        public String getMyName() {
            return name;
        }
        
        @Override
        public void run() {
            System.out.println(name + ": begin to sleep");
            try {
                TimeUnit.MILLISECONDS.sleep(2000);
            } catch (InterruptedException e) {
                System.out.println(name + " was interrupted");
                return;
            }
            System.out.println(name + ": end sleep");
        }
        
        public static void main(String[] args) {
            ExecutorService exec = Executors.newCachedThreadPool();
            for (int i = 0; i < 5; i++) {
                exec.execute(new SleepTask("Sleeper"));
            }
            exec.shutdown();
        }
    }
    
    package threadtest;
    
    import java.util.concurrent.TimeUnit;
    
    public class JoinThread extends Thread {
        private String name;
        private SleepTask sleeper;
        
        public JoinThread(String name, SleepTask sleeper) {
            this.name = name;
            this.sleeper = sleeper;
        }
    
        @Override
        public void run() {
            try {
                System.out.println(name + ": waiting for sleeper: " + sleeper.getMyName());
                TimeUnit.MILLISECONDS.sleep(100);
                // 有了join的介入,这个线程会挂起,必须等到sleeper线程执行完毕才能继续执行 
                // 除非sleeper线程执行了interrupt()方法
                sleeper.join();
                System.out.println(name + ": sleeper join end " + sleeper.getMyName() + ": " + sleeper.isAlive());
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        
        public static void main(String[] args) {
            SleepTask sleeper = new SleepTask("sleeper1");
            SleepTask sleeper2 = new SleepTask("sleeper2");
            sleeper.start();
            sleeper2.start();
            (new JoinThread("join1", sleeper)).start();
            (new JoinThread("join2", sleeper2)).start();
            sleeper2.interrupt();
        }
    }

    sleeper1: begin to sleep
    sleeper2: begin to sleep
    join1: waiting for sleeper: sleeper1
    sleeper2 was interrupted
    join2: waiting for sleeper: sleeper2
    join2: sleeper join end sleeper2: false
    sleeper1: end sleep
    join1: sleeper join end sleeper1: false

    package threadtest;
    
    public class Accessor extends Thread {
        @Override
        public void run() {
            while (!Thread.currentThread().isInterrupted()) {
                // 独立的本地存储数字
                ThreadLocalVarHolder.increment();
                System.out.println(this);
                Thread.yield();
            }
        }
    
        @Override
        public String toString() {
            return Thread.currentThread() + "# id : " + ThreadLocalVarHolder.get();
        }
    }
    
    package threadtest;
    
    import java.util.Random;
    import java.util.concurrent.ExecutorService;
    import java.util.concurrent.Executors;
    import java.util.concurrent.TimeUnit;
    
    public class ThreadLocalVarHolder {
        // 使用ThreadLocal,在线程使用他时会分配独立本地存储,互不干扰
        private static ThreadLocal<Integer> value =
                new ThreadLocal<Integer>() {
            private Random rand = new Random(47);
    
            @Override
            protected Integer initialValue() {
                return rand.nextInt(1000);
            }
        };
        
        public static void increment() {
            value.set(value.get() + 1);
        }
        
        public static int get() {
            return value.get();
        }
        
        public static void main(String[] args) {
            ExecutorService exec = Executors.newCachedThreadPool();
            for (int i = 0; i < 5; i++)
                exec.execute(new Accessor());
            try {
                TimeUnit.MILLISECONDS.sleep(100);
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            exec.shutdownNow();
        }
    }

    Thread[pool-1-thread-1,5,main]# id : 259
    Thread[pool-1-thread-2,5,main]# id : 556
    Thread[pool-1-thread-3,5,main]# id : 694
    Thread[pool-1-thread-2,5,main]# id : 557
    Thread[pool-1-thread-2,5,main]# id : 558
    Thread[pool-1-thread-2,5,main]# id : 559
    Thread[pool-1-thread-3,5,main]# id : 695
    Thread[pool-1-thread-2,5,main]# id : 560
    Thread[pool-1-thread-3,5,main]# id : 696
    Thread[pool-1-thread-2,5,main]# id : 561
    Thread[pool-1-thread-2,5,main]# id : 562
    Thread[pool-1-thread-3,5,main]# id : 697
    Thread[pool-1-thread-2,5,main]# id : 563
    Thread[pool-1-thread-3,5,main]# id : 698
    Thread[pool-1-thread-2,5,main]# id : 564
    Thread[pool-1-thread-3,5,main]# id : 699
    Thread[pool-1-thread-2,5,main]# id : 565
    Thread[pool-1-thread-3,5,main]# id : 700
    Thread[pool-1-thread-2,5,main]# id : 566
    Thread[pool-1-thread-3,5,main]# id : 701
    Thread[pool-1-thread-2,5,main]# id : 567
    Thread[pool-1-thread-3,5,main]# id : 702
    Thread[pool-1-thread-2,5,main]# id : 568
    Thread[pool-1-thread-3,5,main]# id : 703
    Thread[pool-1-thread-2,5,main]# id : 569
    Thread[pool-1-thread-3,5,main]# id : 704

    后台线程:后台线程的效果是程序不会等待后台线程的执行,而是后台线程会随着程序的执行完毕而结束

    package threadtest;
    
    import java.util.concurrent.TimeUnit;
    
    public class DaemonThreadTest {
        class MyThread extends Thread {
            @Override
            public void run() {
                // 注意此处 sleep() 的作用,他是为了让 main() 里的 print 先输出 
                try {
                    TimeUnit.MILLISECONDS.sleep(100);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println(Thread.currentThread() + " : Thread run");
            }
        }
        
        public static void main(String[] args) throws InterruptedException {
            for (int i = 0; i < 5; i++) {
                Thread t = (new DaemonThreadTest()).new MyThread();
                t.setDaemon(true);    // 设置为后台线程
                t.start();
            }
            System.out.println("All daemons prepared");
            
            
             // 如果将这句 sleep 注释掉,那么run方法里的打印将不会输出
             // 这是因为 daemon 后台线程会随着 main 方法的结束而结束
            TimeUnit.MILLISECONDS.sleep(1000);
        }
    }

    All daemons prepared
    Thread[Thread-1,5,main] : Thread run
    Thread[Thread-2,5,main] : Thread run
    Thread[Thread-0,5,main] : Thread run
    Thread[Thread-3,5,main] : Thread run
    Thread[Thread-4,5,main] : Thread run

  • 相关阅读:
    VS2010不能引用System.Data.OracleClient解决方法(转)
    stdafx.h的作用(转载)
    生成缩略图
    java 泛型 入门
    itext库产生word文档示例(.doc)
    json(在JSP中) 应用实例
    C/C++ 指针应用 常见问题
    Java RTTI 和 反射机制
    Hibernate DAO类三个函数:merge() attachDirty() attachClean()
    HTTPSession 简介
  • 原文地址:https://www.cnblogs.com/zemliu/p/2937684.html
Copyright © 2011-2022 走看看