- 线程的创建方式
class TaskWithResult implements Callable<String>{ private int id; public TaskWithResult(int id) { this.id = id; } @Override public String call() throws Exception { return "result of taskResult is " +id; } public static void main(String[] args) { ExecutorService executorService = Executors.newCachedThreadPool(); List<Future<String>> list = new ArrayList<>(); for (int i = 0; i < 5; i++) { Future<String> future = executorService.submit(new TaskWithResult(i)); list.add(future); } try { for (Future<String> future : list) { if(future.isDone()){ System.out.println(future.get()); }//也可以直接调用get方法,这个时候get会被阻塞,直到task完成之后才被执行 } } catch (InterruptedException e) { e.printStackTrace(); } catch (ExecutionException e) { e.printStackTrace(); } } }
public class TestRunable implements Runnable{ protected int countDown = 10; private static int taskCount = 0;//当前运行的线程计数 private final int id = taskCount++;//当前线程id标记 public String status() { return "#" + id + "(" + (countDown > 0 ? countDown : "lifeOff") + ")." + taskCount; } @Override public void run() { while (countDown >= 0) { System.out.println(status()); Thread.yield(); countDown--; } } public static void main(String[] args){ for(int i=0;i<5;i++) { Thread t = new Thread(new LifeOff()); t.start(); } } }
public class TestThread extends Thread{ protected int countDown = 10; private static int taskCount = 0;//当前运行的线程计数 private final int id = taskCount++;//当前线程id标记 public String status() { return "#" + id + "(" + (countDown > 0 ? countDown : "lifeOff") + ")." + taskCount; } public void run(){ while(countDown >= 0){ System.out.println(status()); Thread.yield(); countDown--; } } public static void main(String[] args){ for(int i=0;i<5;i++){ Thread a = new TestThread(); a.start(); } } }
- java线程管理(线程包装器Executors)
class LifeOff implements Runnable { protected int countDown = 10; private static int taskCount = 0; private final int id = taskCount++; public LifeOff() {} public LifeOff(int countDown) { this.countDown = countDown; } public String status() { return "#" + id + "(" + (countDown > 0 ? countDown : "lifeOff") + ")." + taskCount; } @Override public void run() { while (countDown >= 0) { System.out.println(status()); Thread.yield(); countDown--; } } } public class JunitTest{ public void static main(String[] args){ //创建一个最小线程未0,最大为2的31次方-1,存活时间为60s(空闲线程的存活时间)的线程池 //会创建和所需数量相同的线程(一个任务对应一个线程),在回收线程时(当线程超过最大容量,且闲置时间超过设置的时间时)停止创建线程 //是相对合理的线程管理对象 ExecutorService service = Executors.newCachedThreadPool(); //当newCachedThreadPool可能会发生问题时,应该考虑另一种方式(指定创建的线程数量) ExecutorService service = Executors.newFixThreadPool(3); //当需要在某一个线程中长期运行某个任务时,你需要使用SingleThreadExecutor,这个是线程数量为1的FixedTheadPool //任何时间任何线程都只有一个任务在运行 ExecutorService service = Executors.newSingleThreadExecutor(); for(int i=0;i<5;i++){ service.execute(new LifeOff()); } service.shutdown(); } }
- 优先级(听起来好像很高大上,但是我能说没看懂么,测试貌似没什么卵用)
class SimplePriorities implements Runnable { private int countDown = 5; private int priority; private volatile double d; public SimplePriorities(int priority) { this.priority = priority; } @Override public String toString() { return Thread.currentThread() + ":" + countDown; } @Override public void run() { Thread.currentThread().setPriority(priority); //通过大量浮点运算,来让线程优先级调度介入,从而主动控制线程(貌似没什么效果,应该还是和OS对CPU调度有关) while (true) { for (int i = 0; i < 100000; i++) { d += (Math.PI + Math.E) / (double) i; if (i % 1000 == 0) { Thread.yield(); } } System.out.println(this); if (--countDown == 0) { return; } } } public static void main(String[] args) { ExecutorService executorService = Executors.newCachedThreadPool(); for (int i = 0; i < 5; i++) { executorService.execute(new SimplePriorities(Thread.MIN_PRIORITY)); executorService.execute(new SimplePriorities(Thread.MAX_PRIORITY)); } executorService.shutdown(); } }
- 后台线程:通过setDaemon(true)可以设置线程未后台运行,且必须在start()调用前设置;且当所有非后台线程结束后(程序终止),后台线程自动结束
/** * 后台线程 * 当所有非后台线程结束后,则后台线程自动结束 * 可以通过修改sleep的时间可以明显看到效果 */ class SimpleDaemon implements Runnable{ @Override public void run() { try { //这里写一个死循环,无限执行当前线程的打印 while (true) { System.out.println(Thread.currentThread()+"..."+this); TimeUnit.MILLISECONDS.sleep(100);//等同Thread.currentThread().sleep(100) } } catch (InterruptedException e) { e.printStackTrace(); } } public static void main(String[] args) { for (int i=0;i<10;i++) { Thread thread = new Thread(new SimpleDaemon()); //设置要执行的线程未后台线程:必须在执行前设置 thread.setDaemon(true); thread.start(); } System.out.println("SimpleDaemon start"); try { TimeUnit.MILLISECONDS.sleep(200); } catch (InterruptedException e) { e.printStackTrace(); } } }
//通过实现ThreadFactory来设置线程的一些属性,比如优先级、名称、是否为后台线程(priority,name,daemon等) class DaemonThreadFactory implements ThreadFactory{ @Override public Thread newThread(Runnable r) { Thread thread = new Thread(r); thread.setDaemon(true); return thread; } } class DaemonFromFactory implements Runnable { @Override public void run() { try { //这里写一个死循环,无限执行当前线程的打印 while (true) { TimeUnit.MILLISECONDS.sleep(100);//等同Thread.currentThread().sleep(100) System.out.println(Thread.currentThread()+"..."+this); } } catch (InterruptedException e) { e.printStackTrace(); } } public static void main(String[] args) throws Exception { //通过Executors.newCachedThreadPool(ThreadFactory f)来设置线程的属性 ExecutorService executorService = Executors.newCachedThreadPool(new DaemonThreadFactory()); for (int i=0;i<10;i++) { executorService.execute(new DaemonFromFactory()); } System.out.println("SimpleDaemon start"); TimeUnit.MILLISECONDS.sleep(200); executorService.shutdown(); } }
- 线程协作(wait --- notifyAll)
/** * synchronized wait -- notifyAll方式 * car的抛光和打蜡的并发操作 */ class Car { /*打蜡是否OK的标记*/ private boolean waxOn = false; /*已经打好蜡OK了,等待抛光*/ public synchronized void waxed() { waxOn = true; notifyAll(); } /*已经抛光OK了,等待打蜡*/ public synchronized void buffed() { waxOn = false; notifyAll(); } /*如果未打蜡,则等待打蜡*/ public synchronized void waitForWax()throws InterruptedException { while (waxOn == false) { wait(); } } /*如果打蜡OK了,则等待抛光*/ public synchronized void waitForBuffed() throws InterruptedException { while (waxOn == true) { wait(); } } } /** * 打蜡 */ class WaxOn implements Runnable { private Car car; public WaxOn(Car car) { this.car = car; } @Override public void run() { try { while (!Thread.interrupted()) { /*先判断当前车是否打蜡OK,如果OK,则修改打蜡标记,然后等待抛光*/ // car.waitForWax(); car.waxed(); System.out.println("打蜡完成。。。"); car.waitForBuffed(); } } catch (InterruptedException e) { e.printStackTrace(); } } } /** * 抛光 */ class Buffed implements Runnable { private Car car; public Buffed(Car car) { this.car = car; } @Override public void run() { try { while (!Thread.interrupted()) { /*先判断是否打蜡OK了,如果打蜡OK,则进行抛光,然后等待打蜡*/ car.waitForWax(); System.out.println("正在抛光中。。。"); car.buffed(); // car.waitForWax(); } } catch (InterruptedException e) { e.printStackTrace(); } } } class CarTest { public static void main(String[] args) throws InterruptedException{ Car car = new Car(); ExecutorService executorService = Executors.newCachedThreadPool(); for (int i=0;i<3;i++) { executorService.execute(new WaxOn(car)); executorService.execute(new Buffed(car)); TimeUnit.MILLISECONDS.sleep(1); } executorService.shutdownNow(); } }
/** * lock方式 * car的抛光和打蜡的并发操作 */ class Car { /*打蜡是否OK的标记*/ private boolean waxOn = false; private Lock lock = new ReentrantLock(); private Condition condition = lock.newCondition(); /*已经打好蜡OK了,等待抛光*/ public void waxed() { lock.lock(); try { waxOn = true; condition.signalAll(); } finally { lock.unlock();/*任何情况下都要保证释放锁*/ } } /*已经抛光OK了,等待打蜡*/ public void buffed() { lock.lock(); try { waxOn = false; condition.signalAll(); } finally { lock.unlock(); } } /*如果未打蜡,则等待打蜡*/ public void waitForWax()throws InterruptedException { lock.lock(); try { while (waxOn == false) { condition.await(); } } finally { lock.unlock(); } } /*如果打蜡OK了,则等待抛光*/ public void waitForBuffed() throws InterruptedException { lock.lock(); try { while (waxOn == true) { condition.await(); } } finally { lock.unlock(); } } } /** * 打蜡 */ class WaxOn implements Runnable { private Car car; public WaxOn(Car car) { this.car = car; } @Override public void run() { try { while (!Thread.interrupted()) { /*先判断当前车是否打蜡OK,如果OK,则修改打蜡标记,然后等待抛光*/ // car.waitForWax(); car.waxed(); System.out.println("打蜡完成。。。"); car.waitForBuffed(); } } catch (InterruptedException e) { e.printStackTrace(); } } } /** * 抛光 */ class Buffed implements Runnable { private Car car; public Buffed(Car car) { this.car = car; } @Override public void run() { try { while (!Thread.interrupted()) { /*先判断是否打蜡OK了,如果打蜡OK,则进行抛光,然后等待打蜡*/ car.waitForWax(); System.out.println("正在抛光中。。。"); car.buffed(); // car.waitForWax(); } } catch (InterruptedException e) { e.printStackTrace(); } } } class CarTest { public static void main(String[] args) throws InterruptedException{ Car car = new Car(); ExecutorService executorService = Executors.newCachedThreadPool(); for (int i=0;i<3;i++) { executorService.execute(new WaxOn(car)); executorService.execute(new Buffed(car)); TimeUnit.MILLISECONDS.sleep(1); } executorService.shutdownNow(); } }
/** * linkedBlockingQueue(阻塞队列)方式 * 生产吐司、给吐司添加黄油、给吐司添加果酱 * 吐司 */ class Toast { /*状态:dry空白吐司,buttered添加好黄油的,jamed添加好果酱的*/ public enum Status { DRY("有吐司"), BUTTERED("有黄油"), JAMED("有果酱"); private String name; private Status(String name) { this.name = name; } public String getName() { return name; } } private Status status = Status.DRY; private int id; public Toast(int id) { this.id = id; } /*添加黄油*/ public void butted() { status = Status.BUTTERED; } /*添加果酱*/ public void jamed() { status = Status.JAMED; } public Status getStatus() { return status; } public int getId() { return this.id; } @Override public String toString() { return "Toast " + id + ":" + status.getName(); } } class ToastQueue extends LinkedBlockingQueue<Toast> { /*设置该队列的容量*/ public ToastQueue(int i) { super(i); } } /*生产吐司*/ class Toaster implements Runnable { private ToastQueue toastQueue; private int count = 0; public Toaster(ToastQueue toastQueue) { this.toastQueue = toastQueue; } @Override public void run() { try { while (!Thread.interrupted()) { Toast toast = new Toast(count++); System.out.println(toast); /*添加到已经生产好toast的队列*/ toastQueue.put(toast); } } catch (InterruptedException e) { e.printStackTrace(); } } } /*添加黄油的线程*/ class Buffer implements Runnable { private ToastQueue bufferQueue; private ToastQueue toastQueue; public Buffer(ToastQueue toastQueue, ToastQueue bufferQueue) { this.bufferQueue = bufferQueue; this.toastQueue = toastQueue; } private int count = 0; @Override public void run() { try { while (!Thread.interrupted()) { /*取出toast,添加黄油,并存放在已经添加完黄油队列*/ Toast toast = toastQueue.take(); toast.butted(); System.out.println(toast); bufferQueue.put(toast); } } catch (InterruptedException e) { e.printStackTrace(); } } } class Jamer implements Runnable { private ToastQueue bufferQueue; private ToastQueue jamerQueue; public Jamer(ToastQueue bufferQueue, ToastQueue jamerQueue) { this.bufferQueue = bufferQueue; this.jamerQueue = jamerQueue; } @Override public void run() { try { while (!Thread.interrupted()) { Toast toast = bufferQueue.take(); toast.jamed(); System.out.println(toast); jamerQueue.put(toast); } } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("jam finished"); } } class Finisher implements Runnable { private ToastQueue jamerQueue; private int count; public Finisher(ToastQueue jamerQueue) { this.jamerQueue = jamerQueue; } @Override public void run() { try { while (!Thread.interrupted()) { Toast toast = jamerQueue.take(); if (toast.getId() != count++ || toast.getStatus() != Toast.Status.JAMED) { System.err.println("不是同一块toast,或者没有添加果酱 " + toast); System.exit(1); } else { System.out.println(toast); } } } catch (InterruptedException e) { e.printStackTrace(); } } } class ToastTest { public static void main(String[] args) throws Exception { ToastQueue toastQueue = new ToastQueue(1); ToastQueue bufferQueue = new ToastQueue(1); ToastQueue jamerQueue = new ToastQueue(1); ExecutorService executorService = Executors.newCachedThreadPool(); executorService.execute(new Toaster(toastQueue)); for (int i = 0; i < 5; i++) { executorService.execute(new Buffer(toastQueue, bufferQueue)); executorService.execute(new Jamer(bufferQueue, jamerQueue)); executorService.execute(new Finisher(jamerQueue)); } TimeUnit.MILLISECONDS.sleep(50); executorService.shutdownNow(); } }
/* * 使用管道必须保证输入输出的对象创建完成(如main方法中new2个对象),否则在不同平台会发生不一致问题 * 理论不建议使用管道来操作线程协作,建议使用BlockQueue更方便,也更安全 *管道写入端 * */ class Sender implements Runnable { private PipedWriter pipedWriter; public Sender(PipedWriter pipedWriter) { this.pipedWriter = pipedWriter; } public PipedWriter getPipedWriter() { return pipedWriter; } @Override public void run() { try { while (true) { for (char i = 'A'; i <= 'z'; i++) { pipedWriter.write(i); } TimeUnit.MILLISECONDS.sleep(100); } } catch (IOException e) { e.printStackTrace(); } catch (InterruptedException ee) { ee.printStackTrace(); } } } /*管道接收端*/ class Receiver implements Runnable { private PipedReader reader; private Sender sender; public Receiver(Sender sender) throws Exception{ reader = new PipedReader(sender.getPipedWriter()); } @Override public void run() { try { while (true) { /*使用reader.read()会在线程池调用shutdownNow()时直接截断,无论reader是否有读完*/ System.out.println("Read "+reader.read() + ","); } } catch (IOException e) { e.printStackTrace(); } } } class PipedMain { public static void main(String[] args) throws Exception{ PipedWriter pipedWriter = new PipedWriter(); Sender sender = new Sender(pipedWriter); Receiver receiver = new Receiver(sender); ExecutorService service = Executors.newCachedThreadPool(); service.execute(sender); service.execute(receiver); TimeUnit.MILLISECONDS.sleep(100); service.shutdownNow(); } }
转载于:https://my.oschina.net/qcAtKmTCeCA/blog/727889