|
|
| Java之多线程(2) |
作者:
文章来源:
访问次数:12次
加入时间:2007年04月07日
|
|
线程的其他知识: 线程优先级: 一般线程的优先级越高,得以运行的机会越多。 线程优先级常量: Thread有3个publis tatic final int 成员变量,它们表示可以传递给setPriority()的优先级值的范围。 •Thread.MAX_PRIORITY Thread.MAX_PRIORITY是最高的线程规划优先级,在特定的JVM中传递给setPriority()。一般来说,这个值为10。 •Thread.MIN_PRIORITY Thread.MIN_PRIORITY是最低的线程规划优先级,在特定的JVM中传递给setPriority()。一般来说,这个值为1。 •Thread.NORM_PRIORITY Thread.NORM_PRIORITY是一个不太高,也不是太低的线程规划优先级,也可以传递给setPriority()。一般来说,这个值为5。
判断当前优先级:getPriority() Thread的getPriority()方法返回一个int,它表示线程的当前优先级。一般来说,线程的优先级在它的生存期内不会改变,但也可以改变。 GetPriority.java ?? 使用getPriority() public class GetPriority extends Object { private static Runnable makeRunnable() { Runnable r = new Runnable() { public void run() { for (int i = 0; i < 5; i++) { Thread t = Thread.currentThread(); System.out.println( "in run() - priority=" + t.getPriority() + ", name=" + t.getName());
try { Thread.sleep(2000); } catch (InterruptedException x) { // ignore } } } };
return r; }
public static void main(String[] args) { System.out.println( "in main() - Thread.currentThread().getPriority()=" + Thread.currentThread().getPriority());
System.out.println( "in main() - Thread.currentThread().getName()=" + Thread.currentThread().getName());
Thread threadA = new Thread(makeRunnable(), "threadA"); threadA.start();
try { Thread.sleep(3000); } catch (InterruptedException x) {}
System.out.println("in main() - threadA.getPriority()=" + threadA.getPriority()); } }
更改线程的优先级:setPriority() Thread的setPriority()方法带有一个int作为参数。setPriority()方法可以在启动线程前调用,也可以在运行的时候调用。 SetPriority.java ?? 用setPriority()更改线程的优先级 public class SetPriority extends Object { private static Runnable makeRunnable() { Runnable r = new Runnable() { public void run() { for (int i = 0; i < 5; i++) { Thread t = Thread.currentThread(); System.out.println( "in run() - priority=" + t.getPriority() + ", name=" + t.getName());
try { Thread.sleep(2000); } catch (InterruptedException x) { // ignore } } } };
return r; }
public static void main(String[] args) { Thread threadA = new Thread(makeRunnable(), "threadA"); threadA.setPriority(Thread.MAX_PRIORITY); threadA.start();
Thread threadB = new Thread(makeRunnable(), "threadB"); threadB.setPriority(2); threadB.start();
Runnable r = new Runnable() { public void run() { Thread threadC = new Thread(makeRunnable(), "threadC"); threadC.start(); } }; Thread threadD = new Thread(r, "threadD"); threadD.setPriority(7); threadD.start();
try { Thread.sleep(3000); } catch (InterruptedException x) {}
threadA.setPriority(3); System.out.println("in main() - threadA.getPriority()=" + threadA.getPriority()); } }
先进先出算法(FIFO) 采用数组实现:
SimpleObjectFIFO.java public class SimpleObjectFIFO extends Object { //声明一数组用来保存数据 private Object[] queue; //用于保存数组的总长度 private int capacity; //用于保存当前数组的长度 private int size; //要添加的位置 private int head; //要删除的位置 private int tail;
public SimpleObjectFIFO(int cap) { //初始化数组容器大小 capacity = (cap > 0) ? cap : 1; // at least 1 //开辟一个capacity大小的对象数组 queue = new Object[capacity]; //要添加的位置为0 head = 0; //要删除的位置为0 tail = 0; //数组的内容为0 size = 0; }
public synchronized int getSize() { //得到数组的当前大小 return size; }
public synchronized boolean isFull() { //判断数组是否已经存满 return (size == capacity); }
public synchronized void add(Object obj) throws InterruptedException { //向数组中添加一个元素 //如果数组已经满了,则让其他线程等待 while (isFull()) { wait(); } queue[head] = obj; //修改位置指针 /* head += 1 ; if(head>=5) head = 0 ; */ head = (head + 1) % capacity; //内容的容量加1 size++;
notifyAll(); //唤醒其他线程继续执行 } //从数组中移除对象 public synchronized Object remove() throws InterruptedException { //如果当前的容量size为零,表示没有内容,则线程等待 while (size == 0) { wait(); } //否则执行此处 //从对象数组中取出数据 Object obj = queue[tail]; //修改里面的内容让其等于null queue[tail] = null; //修改删除的位置 tail = (tail + 1) % capacity; //容量减1 size--; //唤醒其他线程 notifyAll(); //返回取出的对象 return obj; } //此方法用于打印 public synchronized void printState() { StringBuffer sb = new StringBuffer();
sb.append("SimpleObjectFIFO:
"); sb.append(" capacity=" + capacity + "
");
sb.append(" size=" + size); if (isFull()) { sb.append(" - FULL"); } else if (size == 0) { sb.append(" - EMPTY"); } sb.append("
");
sb.append(" head=" + head + "
"); sb.append(" tail=" + tail + "
");
for (int i = 0; i < queue.length; i++) { sb.append(" queue[" + i + "]=" + queue[i] + "
"); }
System.out.print(sb); } }
SimpleObjectFIFOTest.java public class SimpleObjectFIFOTest extends Object { public static void main(String[] args) { try { SimpleObjectFIFO fifo = new SimpleObjectFIFO(5); fifo.printState();
fifo.add("S01"); fifo.printState();
fifo.add("S02"); fifo.printState();
fifo.add("S03"); fifo.printState();
Object obj = fifo.remove(); System.out.println("just removed obj=" + obj); fifo.printState();
fifo.add("S04"); fifo.printState();
fifo.add("S05"); fifo.printState();
fifo.add("S06"); fifo.printState(); } catch (InterruptedException x) { x.printStackTrace(); } } }
下面再看一个更好的实现方法,此方法在上一方法上进行了修改 ObjectFIFO.java public class ObjectFIFO extends Object { //声明一对象数组 private Object[] queue; //数组的初始容量 private int capacity; //数组的当前长度 private int size; //要添加的位置 private int head; //要删除的位置 private int tail;
public ObjectFIFO(int cap) { //实例化此类,并同时传入数组容量 capacity = (cap > 0) ? cap : 1; //势力化对象数组 queue = new Object[capacity]; //添加的位置为0 head = 0; //删除的位置为0 tail = 0; //内容长度为0 size = 0; } //得到数组的容量 public int getCapacity() { return capacity; }
//得到数组中当前的长度(内容) public synchronized int getSize() { return size; }
//判断数组是否为空 public synchronized boolean isEmpty() { return (size == 0); } //判断是否数组已满 public synchronized boolean isFull() { return (size == capacity); }
//向数组中添加数据 public synchronized void add(Object obj) throws InterruptedException { //调用waitWhileFull()方法 waitWhileFull(); //想数组中添加内容 queue[head] = obj; //修改要添加的位置 head = (head + 1) % capacity; //数组的长度加1 size++; //唤醒其他线程 notifyAll(); }
//加入一个数组 public synchronized void addEach(Object[] list) throws InterruptedException {
//在这里用for循环将传入的数组内容依次加入到对象数组之中 for (int i = 0; i < list.length; i++) { add(list[i]); } } //从数组中移出内容 public synchronized Object remove() throws InterruptedException { //调用waitWhileEmpty()方法 waitWhileEmpty(); //从对象数组之中取出内容 Object obj = queue[tail]; //取出内容后将此数组的内容请空 queue[tail] = null; //修改删除位置 tail = (tail + 1) % capacity; //长度减1 size--; //唤醒其他等待的线程序继续执行 notifyAll(); //返回取出的对象 return obj; } //此方法用于移出所有内容 public synchronized Object[] removeAll() throws InterruptedException { //使用当前的长度初始化一个对象数组 Object[] list = new Object[size]; //用for循环调用remove()方法 for (int i = 0; i < list.length; i++) { list[i] = remove(); } return list; }
//等待数组中至少只有一个项之后删除该项 public synchronized Object[] removeAtLeastOne() throws InterruptedException { //调用waitWhileEmpty方法用于判断内容是否为空 waitWhileEmpty(); return removeAll(); }
public synchronized boolean waitUntilEmpty(long msTimeout) throws InterruptedException { //如果msTimeout为零,则调用waitUntilEmpty()方法 if (msTimeout == 0L) { waitUntilEmpty(); // use other method return true; }
// 等待指定的时间量 long endTime = System.currentTimeMillis() + msTimeout; long msRemaining = msTimeout;
while (!isEmpty() && (msRemaining > 0L)) { wait(msRemaining); msRemaining = endTime - System.currentTimeMillis(); }
// 可能超时,也可能满足了条件,计算返回值 return isEmpty(); } //此方法用于判断单元中的内容是否为空 public synchronized void waitUntilEmpty() throws InterruptedException {
while (!isEmpty()) { wait(); } }
//此方法用于判断数组中的内容是否为空,如果为空则等待 public synchronized void waitWhileEmpty() throws InterruptedException {
while (isEmpty()) { wait(); } }
public synchronized void waitUntilFull() throws InterruptedException {
while (!isFull()) { wait(); } }
//此方法判断数组中的内容是否已满,如果已满的话则让其他线程等待 public synchronized void waitWhileFull() throws InterruptedException {
while (isFull()) { wait(); } } }
ObjectFIFOTest.java public class ObjectFIFOTest extends Object {
private static void fullCheck(ObjectFIFO fifo) { try { //同步化方法允许条件仍然为true时打印信息 synchronized (fifo) { while (true) { //调用ObjectFIFO中的waitUntilFull()方法用于判断单元中的内容是否已满 fifo.waitUntilFull(); print("FULL"); //如果有线程等待,则不打印“NO LONGER FULL”这句话 fifo.waitWhileFull(); print("NO LONGER FULL"); } } } catch (InterruptedException ix) { return; } }
//此方法用于检测内容是否为空 private static void emptyCheck(ObjectFIFO fifo) { try { // 同步化方法允许条件仍然为true时打印信息 synchronized (fifo) { while (true) { //调用waitUntilEmpty()方法,判断数组中的内容是否为空 fifo.waitUntilEmpty(); //如果为空则打印此句 print("EMPTY"); //等待数组中的内容直到空的时候 fifo.waitWhileEmpty(); //如果不为空则打印“NO LONGER EMPTY” print("NO LONGER EMPTY"); } } } catch (InterruptedException ix) { return; } } //此方法用于从数组中取出数据 private static void consumer(ObjectFIFO fifo) { try { print("just entered consumer()"); //从数组中取出三个数据 for (int i = 0; i < 3; i++) { synchronized (fifo) { //调用remove()方法,返回obj对象 Object obj = fifo.remove(); //打印取出的对象 print("DATA-OUT - did remove(), obj=" + obj); } //休眠3秒 Thread.sleep(3000); }
synchronized (fifo) { //设立一个等待时间 boolean resultOfWait = fifo.waitUntilEmpty(500); print("did waitUntilEmpty(500), resultOfWait=" + resultOfWait + ", getSize()=" + fifo.getSize()); } //调用三次removeAll方法 for (int i = 0; i < 3; i++) { synchronized (fifo) { Object[] list = fifo.removeAll(); print("did removeAll(), list.length=" + list.length);
for (int j = 0; j < list.length; j++) { print("DATA-OUT - list[" + j + "]=" + list[j]); } } Thread.sleep(100); } for (int i = 0; i < 3; i++) { synchronized (fifo) { Object[] list = fifo.removeAtLeastOne(); print( "did removeAtLeastOne(), list.length=" + list.length);
for (int j = 0; j < list.length; j++) { print("DATA-OUT - list[" + j + "]=" + list[j]); } } Thread.sleep(1000); }
while (!fifo.isEmpty()) { synchronized (fifo) { //调用remove()方法移除一项 Object obj = fifo.remove(); print("DATA-OUT - did remove(), obj=" + obj); } Thread.sleep(1000); }
print("leaving consumer()"); } catch (InterruptedException ix) { return; } }
private static void producer(ObjectFIFO fifo) { try { print("just entered producer()"); int count = 0;
Object obj0 = new Integer(count); count++; synchronized (fifo) { //想数组之中放入一个对象 fifo.add(obj0); print("DATA-IN - did add(), obj0=" + obj0);
//返回数组中的内容是否为空 boolean resultOfWait = fifo.waitUntilEmpty(500); print("did waitUntilEmpty(500), resultOfWait=" + resultOfWait + ", getSize()=" + fifo.getSize()); } //向数组中放入十个内容 for (int i = 0; i < 10; i++) { Object obj = new Integer(count); count++; synchronized (fifo) { fifo.add(obj); print("DATA-IN - did add(), obj=" + obj); } Thread.sleep(1000); }
Thread.sleep(2000);
Object obj = new Integer(count); count++; //休眠两秒之后再向数组中放入一个内容 synchronized (fifo) { fifo.add(obj); print("DATA-IN - did add(), obj=" + obj); } Thread.sleep(500);
Integer[] list1 = new Integer[3]; for (int i = 0; i < list1.length; i++) { list1[i] = new Integer(count); count++; }
//向数组之中放入一个数组 synchronized (fifo) { fifo.addEach(list1); print("did addEach(), list1.length=" + list1.length); }
Integer[] list2 = new Integer[8]; for (int i = 0; i < list2.length; i++) { list2[i] = new Integer(count); count++; }
//向数组之中放入一个数组 synchronized (fifo) { fifo.addEach(list2); print("did addEach(), list2.length=" + list2.length); } synchronized (fifo) { //等待单元为空 fifo.waitUntilEmpty(); //如果为空了,则打印此句 print("fifo.isEmpty()=" + fifo.isEmpty()); }
print("leaving producer()"); } catch (InterruptedException ix) { return; } }
private static synchronized void print(String msg) { System.out.println( Thread.currentThread().getName() + ": " + msg); }
public static void main(String[] args) { final ObjectFIFO fifo = new ObjectFIFO(5);
//实例化此线程类 Runnable fullCheckRunnable = new Runnable() { public void run() { fullCheck(fifo); } };
Thread fullCheckThread = new Thread(fullCheckRunnable, "fchk"); //设置线程的优先级为9 fullCheckThread.setPriority(9); //设置线程为后台运行 fullCheckThread.setDaemon(true); // die automatically //启动线程 fullCheckThread.start(); //启动另外一个线成 Runnable emptyCheckRunnable = new Runnable() { public void run() { emptyCheck(fifo); } };
Thread emptyCheckThread = new Thread(emptyCheckRunnable, "echk"); emptyCheckThread.setPriority(8); emptyCheckThread.setDaemon(true); // die automatically emptyCheckThread.start();
Runnable consumerRunnable = new Runnable() { public void run() { consumer(fifo); } };
Thread consumerThread = new Thread(consumerRunnable, "cons"); consumerThread.setPriority(7); consumerThread.start();
Runnable producerRunnable = new Runnable() { public void run() { producer(fifo); } };
Thread producerThread = new Thread(producerRunnable, "prod"); producerThread.setPriority(6); producerThread.start(); } }
练习题3: /* 设计4个线程,其中两个线程每次对j增加1,另外两个线程对j每次减少1。写出程序。
*/ public class ThreadTest1{ private int j; public static void main(String args[]){ ThreadTest1 tt=new ThreadTest1(); Inc inc=tt.new Inc(); Dec dec=tt.new Dec(); for(int i=0;i<2;i++){ Thread t=new Thread(inc); t.start(); t=new Thread(dec); t.start(); } } private synchronized void inc(){ j++; System.out.println(Thread.currentThread().getName()+"-inc:"+j); } private synchronized void dec(){ j--; System.out.println(Thread.currentThread().getName()+"-dec:"+j); }
/***************************************************************************/
class Inc implements Runnable{ public void run(){ for(int i=0;i<100;i++){ inc(); } } } class Dec implements Runnable{ public void run(){ for(int i=0;i<100;i++){ dec(); } } } } class Inc implements Runnable { Q q ; public Inc(Q q) { this.q = q ; } public void run() { for(int i=0;i<10;i++) { q.inc(); } } }
class Dec implements Runnable { Q q ; public Dec(Q q) { this.q = q ; } public void run() { for(int i=0;i<10;i++) { q.dec(); } } } class Q { private int j; public synchronized void inc(){ j++; System.out.println(Thread.currentThread().getName()+"-inc:"+j); } public synchronized void dec(){ j--; System.out.println(Thread.currentThread().getName()+"-dec:"+j); } } public class ThreadTest{ public static void main(String args[]){ Q q = new Q() ; Inc i = new Inc(q); Dec d = new Dec(q) ; for(int k=0;k<2;k++){ Thread t ; t= new Thread(i) ; t.start(); t=new Thread(d); t.start(); } } }
|
|
|