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

原文地址:https://www.cnblogs.com/zemliu/p/2937684.html