电脑太差,不敢开太多线程,不知道大量线程是否有问题
有条件的朋友,如果发现有问题,烦请告知我下!非常感谢!!!
package ThreadTest.test1;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicReference;
import java.util.concurrent.atomic.AtomicStampedReference;
/**
* 数组方式
* 栈:先进后出,后进先出
* 实现一个无锁的Stack,并写一段测试代码(多线程访问),证明这个Stack是线程安全的。给出程序以及运行的截图。
* 关键点:无锁须利用CAS类
* Created by lizq on 2019/4/22.
*/
public class TestMain3<T> {
/**
* 数组长度
*/
private final static Integer MAX_LENGTH = 3;
/**
* 存放数据
*/
private AtomicReference<T>[] arrayStack = new AtomicReference[MAX_LENGTH];
/**
* 顶端指针
*/
private static AtomicInteger index = new AtomicInteger(0);
private static AtomicStampedReference<Integer> sIndex = new AtomicStampedReference<Integer>(0,0);
/**
* 验证
*/
private static AtomicInteger pushj = new AtomicInteger(0);
private static AtomicInteger popj = new AtomicInteger(0);
/**
* 初始化
*/ {
for (int i = 0; i < MAX_LENGTH; i++) {
arrayStack[i] = new AtomicReference();
}
}
/**
* 压入元素
*
* @param t
*/
public void push(T t) {
Integer i = 0;
while (true) {
// 1、获取当前位置
i = sIndex.getReference();
if (i > MAX_LENGTH - 1) {
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
// 越位,重新抢
System.out.println("数组已经达到最大长度,请等待!");
continue;
}
// 2、抢位置
// index.compareAndSet(i, i + 1)
if (sIndex.compareAndSet(i,i+1,sIndex.getStamp(),sIndex.getStamp()+1)) {
// 3、执行业务
if(arrayStack[i].compareAndSet(null, t)){
// 4、退出
break;
}
}
}
pushj.incrementAndGet();
System.out.println(" push 成功!num: " + i + " val: " + t.toString());
}
/**
* 弹出元素
* @return
*/
public T pop() {
Integer i = 0;
T t = null;
while(true){
// 1、先抢位置
i = sIndex.getReference() -1;
if (i < 0) {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
// 越位,重新抢
System.out.println("stack为空,请等待!");
continue;
}
if (i < MAX_LENGTH ) {
if(sIndex.compareAndSet(i+1,i,sIndex.getStamp(),sIndex.getStamp()+1)){
if(arrayStack[i] != null && arrayStack[i].get() != null){
t = arrayStack[i].get();
if(arrayStack[i].compareAndSet(t, null)){
break;
}
}
}
}
}
popj.incrementAndGet();
return t;
}
static TestMain3<Object> test = new TestMain3<Object>();
public static void main(String[] args) throws InterruptedException {
for (int i = 0; i < 40; i++) {
new Thread("thread:" + i) {
@Override
public void run() {
super.run();
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
for (int j = 0; j < 30; j++) {
System.out.println(" pop 成功!val: " + test.pop().toString());
}
}
}.start();
}
for (int i = 0; i < 40; i++) {
new Thread("thread:" + i) {
@Override
public void run() {
super.run();
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
for (int j = 0; j < 30; j++) {
test.push(this.getName() + " Random->" + j);
}
}
}.start();
}
// Thread.sleep(1000);
// System.out.println("push num: " + index.get());
// for (int i = 0; i < test.arrayStack.length; i++) {
// System.out.println(i + " " + test.arrayStack[i].get() + " ");
// }
Thread.sleep(300000);
System.out.println(pushj);
System.out.println(popj);
System.out.println(index);
for (int i = 0; i < test.arrayStack.length; i++) {
if(test.arrayStack[i].get() != null){
System.out.println(i + " " + test.arrayStack[i].get() + " ");
}
}
}
}
