本来没打算写这个帖子的。但是由于本人貌似被列入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());
}
}
好了,写到这里吧。别拍砖。回帖一律 智力+ 体力+ 攻击+ 敏捷+ 幸运+ 力量+ 暴率+
最后祝大家中秋快乐!国庆快乐!
版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。