关于Java非阻塞多线程的实现:报错 -问答-阿里云开发者社区-阿里云

开发者社区> 问答> 正文
阿里云
为了无法计算的价值
打开APP
阿里云APP内打开

关于Java非阻塞多线程的实现:报错

2020-06-14 09:05:09 356 0

本来没打算写这个帖子的。但是由于本人貌似被列入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());
	}
}

好了,写到这里吧。别拍砖。回帖一律 智力+ 体力+ 攻击+ 敏捷+ 幸运+ 力量+ 暴率+
最后祝大家中秋快乐!国庆快乐!

取消 提交回答
全部回答(0)
相关问答

0

回答

请问java性能问题:如何优化向HashMap插入元素的速度?

2021-11-12 17:18:18 134浏览量 回答数 0

0

回答

请问java中使用BigDecimal计算操作性能最优的做法是什么?

2021-11-07 15:42:19 211浏览量 回答数 0

1

回答

java性能问题:有没有比较字符串是否相等的最快方法?

2021-11-06 16:21:40 167浏览量 回答数 1

0

回答

您好java性能问题:有没有比较字符串是否相等的最快方法?

2021-11-07 00:39:14 143浏览量 回答数 0

1

回答

java性能问题:如何优化向HashMap插入元素的速度?

2021-11-06 15:41:34 212浏览量 回答数 1

1

回答

java中常用的性能调优诊断工具都有哪些,请帮忙提供一下?

2021-11-06 10:24:39 158浏览量 回答数 1

0

回答

请问java中常用的性能调优诊断工具都有哪些,请帮忙提供一下?

2021-11-06 22:35:44 85浏览量 回答数 0

1

回答

java中使用BigDecimal计算操作性能最优的做法是什么?

2021-11-06 16:35:15 226浏览量 回答数 1

1

回答

java中DoubleBufferedQueue与ArrayBlockingQueue哪个性能更高?

2021-11-06 21:50:01 184浏览量 回答数 1

1

回答

java中ArrayBlockingQueue与DoubleBufferedQueue哪个性能更高?

2021-11-06 21:47:49 205浏览量 回答数 1
+关注
0
文章
13395
问答
问答排行榜
最热
最新
相关电子书
更多
低代码开发师(初级)实战教程
立即下载
阿里巴巴DevOps 最佳实践手册
立即下载
冬季实战营第三期:MySQL数据库进阶实战
立即下载