本来没打算写这个帖子的。但是由于本人貌似被列入osc的黑名单(回帖过了40分钟也看不见),所以写这个帖子没有任何目的,不为技术分享,只是增加点个人RP,并希望早日从黑名单里面除名。
这个问题是昨天我回答一个多线程按照一定顺序打印字符的帖子。我把问题简化下:4个线程,每个线程只打印一个的字符。给出一个字符串,要求启动4个线程打印出给定字符串。
比如 Thread1只打印 'A' Thread2只打印 'B' Thread3只打印 'C' Thread4只打印 'D'. 现在要按顺序打印出ABCDABBACDA.
会线程同步机制的基本都可以秒杀这种题。我在这里给出一个用最基本信号量实现的代码:
package com.gemstone.gemfire.tutorial; import java.util.concurrent.Semaphore; public class CounterSemaphore extends Semaphore { private char[] content; private int pos; public CounterSemaphore(char[] content) { // Must be 1, since we need the semaphore as a mutex here. super(1); this.content = content; } // Throws the Exception to stop the thread. public char getChar() throws ArrayIndexOutOfBoundsException { return content[pos]; } public void next() { this.pos++; } private static final long serialVersionUID = 1L; }
package com.gemstone.gemfire.tutorial; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; public class ThreadCounter implements Runnable { private CounterSemaphore semaphore; public void setSemaphore(CounterSemaphore semaphore) { this.semaphore = semaphore; } private char content; private boolean stop = false; public ThreadCounter(CounterSemaphore semaphore, char content) { this.semaphore = semaphore; this.content = content; } @Override public void run() { try { while (!stop) { if (this.content == semaphore.getChar()) { semaphore.acquire(); System.out.print(this.content +" "); semaphore.next(); semaphore.release(); } } } catch (InterruptedException e) { e.printStackTrace(); stop = true; //Get the notification, stop the thread. } catch (ArrayIndexOutOfBoundsException end) { stop = true; System.out.println("Stop the Thread->"+this.content); } } public static void main(String args[]) { char[] order1 = {'A','B','C','B','A','B','A','B','A','C','A','B','A','B','C','B','A','B','A','B','A','B','A','C','A','C'}; ExecutorService executor = Executors.newFixedThreadPool(5); CounterSemaphore semaphore = new CounterSemaphore(order1); ThreadCounter thread1 = new ThreadCounter(semaphore, 'A'); ThreadCounter thread2 = new ThreadCounter(semaphore, 'B'); ThreadCounter thread3 = new ThreadCounter(semaphore, 'C'); ThreadCounter thread4 = new ThreadCounter(semaphore, 'D'); executor.execute(thread1); executor.execute(thread2); executor.execute(thread3); executor.execute(thread4); executor.shutdown(); } }
先简单普及下非阻塞,简单说就是线程之间没有同步机制,不会因为争抢临界资源而产生阻塞。但是我们又要实现同步,所以用Atomic原子量来控制。
下面是用非阻塞机制实现的:
package com.gemstone.gemfire.tutorial.non; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.atomic.AtomicInteger; public class NonBlockingThreadCounter implements Runnable { private boolean stop; private char content; private char[] input; private char[] result; public NonBlockingThreadCounter(char content, char[] input, AtomicInteger refer, char[] result) { super(); this.content = content; this.input = input; this.refer = refer; this.result = result; } private AtomicInteger refer; @Override public void run() { while (!stop) { int pos; nonBlocking: try { while (true) { pos = this.refer.get(); if (this.content == this.input[pos] && this.refer.compareAndSet(pos, pos + 1)) { result[pos] = this.content; break nonBlocking; } } } catch (Exception e) { System.out.println("Stop thread-->"+this.content); stop = true; } } } public static void main(String args[]) { char[] order1 = {'A','B','C','B','A','B','A','B','A','C','A','B','A','B','C','B','A','B','A','B','A','B','A','C','A','C'}; char[] result = new char[order1.length]; AtomicInteger pos = new AtomicInteger(0); ExecutorService executor = Executors.newFixedThreadPool(3); NonBlockingThreadCounter thread1 = new NonBlockingThreadCounter('A',order1,pos,result); NonBlockingThreadCounter thread2 = new NonBlockingThreadCounter('B',order1,pos,result); NonBlockingThreadCounter thread3 = new NonBlockingThreadCounter('C',order1,pos,result); NonBlockingThreadCounter thread4 = new NonBlockingThreadCounter('D',order1,pos,result); executor.execute(thread1); executor.execute(thread2); executor.execute(thread3); executor.execute(thread4); executor.shutdown(); while(!executor.isTerminated()) {} for(char item : result) { System.out.print(item+" "); } } }
非阻塞优点:
大幅度提升系统性能(尤其是吞吐量)。操作系统告诉我们如果用同步机制,那么必将带来额外的线程调度,当线程持有比较大的资源的时候,调度开销会比较大。非阻塞就不用管这个,各个线程都是自己忙自己的,不用别人调度。
非阻塞缺点:
一个正确的非阻塞代码极其难编写。因为你不能再按照原来信号量,锁,阻塞的思想来编写多线程代码了。在非阻塞代码里面看不见Lock,看不见synchronized,wait,notify.....
任何一行代码在某个时间里面都有可能被所有线程同时访问。
目前正在准备入学考试,最后发一个用非阻塞计算一个定积分的代码。求 y=x^2 与 y轴和x=3 围成的面积,理论值是9. 完全按照定积分的定义做的,可以看到当N越大的时候越接近理论值.
当N=3000000时,结果是 9.000013500006666
package com.gemstone.gemfire.tutorial.non; public class Integration { double area; int i; public Integration(int i) { super(); this.i = i; } public double getArea() { return area; } public void setArea(double area) { this.area = area; } public int getI() { return i; } public void setI(int i) { this.i = i; } public Integration(double area, int i) { super(); this.area = area; this.i = i; } @Override public int hashCode() { return this.getI(); } @Override public boolean equals(Object obj) { if (this == obj) return true; if (obj == null) return false; if (getClass() != obj.getClass()) return false; Integration other = (Integration) obj; if (i != other.i) return false; return true; } }
package com.gemstone.gemfire.tutorial.non; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.atomic.AtomicReference; public class NonBlockingArea implements Runnable { private boolean stop; private AtomicReference<Integration> integration; public static int N = 30000000; public NonBlockingArea(AtomicReference<Integration> integration) { super(); this.integration = integration; } @Override public void run() { Thread: while (!stop) { try { Integration current = null; Integration next = null; do { current = integration.get(); if (current.getI() > N) { stop = true; break Thread; } double deltaX = 3d/N; double fx = Math.pow(((current.getI() + 1)) * deltaX, 2); next = new Integration((deltaX * fx)+current.getArea(), current.getI() + 1); } while (!this.integration.compareAndSet(current, next)); } catch (Exception e) { stop = true; } } System.out.println("Stop thread-->" + Thread.currentThread().getName()); } public static void main(String args[]) { ExecutorService executor = Executors.newFixedThreadPool(3); Integration integration = new Integration(0); AtomicReference<Integration> atomic = new AtomicReference<Integration>( integration); NonBlockingArea thread1 = new NonBlockingArea(atomic); NonBlockingArea thread2 = new NonBlockingArea(atomic); executor.execute(thread1); executor.execute(thread2); executor.shutdown(); while (!executor.isTerminated()) { } System.out.println(atomic.get().getArea()); } }
好了,写到这里吧。别拍砖。回帖一律 智力+ 体力+ 攻击+ 敏捷+ 幸运+ 力量+ 暴率+
最后祝大家中秋快乐!国庆快乐!
版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。