主程序:用来做测试
这里之所以叫Tree是因为我之前写树了,偷懒就直接用了,和卖票的那个性质一样,只不过把买票的数作为下标锁住
import org.omg.Messaging.SyncScopeHelper; import java.lang.reflect.Array; import java.util.Arrays; import java.util.Random; public class TestThread { public static void main(String[] args) { Tree tree = new Tree(); int[] arr = new int[]{1,2,3,4,5,6,7,8,9,10,11,12}; int[] newarr = new int[arr.length]; System.out.println(Arrays.toString(newarr)); tree.value = arr.length-1; ThreadPiao t1 = new ThreadPiao("线程1",tree,arr,newarr); ThreadPiao t2 = new ThreadPiao("线程2",tree,arr,newarr); ThreadPiao t3 = new ThreadPiao("线程3",tree,arr,newarr); t1.start(); t2.start(); t3.start(); try { t1.join();//这样可以使线程提前 t2.join(); t3.join(); }catch (InterruptedException e){ e.printStackTrace(); } System.out.println("~~~~复制结束"+tree.value); } }
Flag类,做信号量来中止进程。
public class Flag { public int flag = 0; }
//这里之所以叫Tree是因为我之前写树了,偷懒就直接用了 import javax.sound.midi.Soundbank; import java.lang.reflect.Array; import java.util.Arrays; public class Tree { int value; public synchronized void copy( int[] arr, int newarr[] , Flag f, String name) { if(value==-1) { f.flag=1;//信号中止线程 return; } newarr[value] = arr[value];//用于赋值 System.out.println(name+" 赋值了:"+newarr[value]+"-- 数组变化为: "+Arrays.toString(newarr)); f.flag = 0;//继续进行 value--; } }
最后是我萌的线程类:
import sun.awt.SunHints; import javax.naming.Name; import javax.sound.midi.Soundbank; public class ThreadPiao extends Thread { private String name; private Tree tree ; private int[] arr,newarr; ThreadPiao(String name, Tree tree,int[] arr,int[] newarr) { this.name = name; this.tree = tree; this.arr = arr; this.newarr = newarr; } public void run() {// synchronized 不用锁run只锁add ,这样的好处是由于此处没加锁_节省效率,<<只锁调用资源的方法就行>> Flag f = new Flag(); while (f.flag==0) { tree.copy(arr,newarr,f,name); try { Thread.sleep(10);//这里是为了让线程的调用更分散,睡眠时间越长,随机性竞争越明显 } catch (Exception e) { e.printStackTrace(); } } } }