* 程序只要有一个非后台(守护)的线程在运行,就不会结束。
public static void main(String[] args) { run(); new MyThread().start(); MyThread mt = new MyThread(); mt.setName("mythread"); //mt.setDaemon(true); //将线程置为后台线程 mt.start(); int num = 0; while(true) { if(num++>20) try{ mt.join(); }catch(Exception e){e.printStackTrace();} break; System.out.println("main() in " + Thread.currentThread().getName()); try{ Thread.sleep(100); } catch(InterruptedException e){e.printStackTrace();} } } static void run() { while(true) { System.out.println("run()"); } } } class MyThread extends Thread { public void run() { while(true) { System.out.println("run() in " + Thread.currentThread().getName()); try{ Thread.sleep(100); } catch(InterruptedException e){e.printStackTrace();} } } } --------------------------------------------------------------------------------- public class TicketsSale1 { /** * 多线程售票,同时开启四个线程售票 * 需要同步的多段代码要用同一把锁 * 死锁: */ public static void main(String[] args) { /*四个线程运行四个售票程序 new SaleThread().start(); new SaleThread().start(); new SaleThread().start(); new SaleThread().start();*/ SaleThread1 st = new SaleThread1(); new Thread(st).start(); new Thread(st).start(); try{ Thread.sleep(10); }catch(Exception e){ e.printStackTrace();} st.lock = "method"; new Thread(st).start(); new Thread(st).start(); } } class SaleThread1 implements Runnable //extends Thread { int tickets = 100; String lock = ""; public void run() { if(lock.equals("method")) { while(true) { sale(); } } else { while(true) { synchronized(lock) { //每个对象都可以作为同步的锁,对象都有一个标志位(0、1),锁旗标 sale(); if(tickets>0) { try{ Thread.sleep(100); }catch(Exception e){ e.printStackTrace();} System.out.println(Thread.currentThread().getName() + " : is sale " + tickets--); } } } } } //同步函数,同步函数用的锁:this (st) public synchronized void sale() { synchronized(lock) { } if(tickets>0) { try{ Thread.sleep(100); }catch(Exception e){ e.printStackTrace();} System.out.println(Thread.currentThread().getName() + " : sale() is sale " + tickets--); } } } ==================================================================================== class SQL { String name; String sex; boolean change = false; } class DBA implements Runnable { private SQL sql; public DBA(SQL sql) { this.sql = sql; } public void run() { int num = 0; while(true) { synchronized(sql) { if(sql.change) try{ sql.wait(); } catch(Exception e){e.printStackTrace();} if(num==0) { sql.name = "hukai"; sql.sex = "male"; } else { sql.name = "shaoyuejiao"; sql.sex = "female"; } //try { Thread.sleep(10);} catch(Exception e){ e.printStackTrace(); } num = (num+1)%2; sql.change = true; sql.notify(); } } } } class Coder implements Runnable { private SQL sql; public Coder(SQL sql) { this.sql = sql; } public void run() { while(true) { synchronized(sql) { if(!sql.change) try{ sql.wait();} catch(Exception e){ e.printStackTrace(); } System.out.print("name=" + sql.name + " ; "); //try { Thread.sleep(10);} catch(Exception e){ e.printStackTrace(); } System.out.println("sex=" + sql.sex); sql.change = false; sql.notify(); } } } } public class SqlThread { /** * @param args */ public static void main(String[] args) { SQL sql = new SQL(); DBA dba = new DBA(sql); Coder coder = new Coder(sql); new Thread(dba).start(); new Thread(coder).start(); } }
-------------------------------------------------------------------------------- //存满了,两个存的线程等待,一个取的线程取了一个元素会唤醒一个存的线程 //存的线程存了一个,又存满了,然而此时它会唤醒,就会唤醒另一个在等待的存的线程,出错了 //解决这个问题很简单,将线程等待的条件放在一个循环里面去判断 //而实际上wait方法允许发声虚假唤醒,所以最好放在一个循环里面 //但是像上面的做法,存的线程会去唤醒存的线程,没有必要,非常影响程序的效率 /*class MyArray { private int[] arr = new int[10]; private String lock = ""; private int savePos = 0; private int getPos = 0; private int count = 0; public void add(int num) { synchronized(lock) { while(count==10) try{ lock.wait(); } catch(Exception e) {e.printStackTrace();} if(savePos==10) savePos = 0; arr[savePos++] = num; count++; lock.notify(); //try{Thread.sleep(10);} catch(Exception e) { e.printStackTrace(); } } } public int get() { synchronized(lock) { try { while(count==0) try{ lock.wait(); } catch(Exception e) {e.printStackTrace();} if(getPos==10) getPos = 0; //try{Thread.sleep(10);} catch(Exception e) { e.printStackTrace(); } count--; return arr[getPos++]; } finally { lock.notify(); } } } }*/ //使用1.5的lock和condition解决存和取之间的通信问题 class MyArray { private int[] arr = new int[10]; private int savePos = 0; private int getPos = 0; private int count = 0; private Lock lock = new ReentrantLock(); private Condition isFull = lock.newCondition(); private Condition isEmpty = lock.newCondition(); public void add(int num) throws InterruptedException { try { lock.lock(); while(count==10) isFull.await(); if(savePos==10) savePos = 0; arr[savePos++] = num; count++; isEmpty.signal(); } finally { lock.unlock(); } //try{Thread.sleep(10);} catch(Exception e) { e.printStackTrace(); } } public int get() throws InterruptedException { try { lock.lock(); while(count==0) isEmpty.await(); if(getPos==10) getPos = 0; //try{Thread.sleep(10);} catch(Exception e) { e.printStackTrace(); } count--; isFull.signal(); return arr[getPos++]; } finally { lock.unlock(); } } } public class ArrayThread { /** * 写一个多线程的程序,实现两个线程存元素,两个线程取元素 */ static int num = 0; public static void main(String[] args) { final MyArray marr = new MyArray(); new Thread(new Runnable() { public void run() { for(int i=0; i<30; i++) { try { marr.add(num++); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } }).start(); new Thread(new Runnable() { public void run() { for(int i=0; i<30; i++) try { System.out.println(marr.get()); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } }).start(); new Thread(new Runnable() { public void run() { for(int i=0; i<30; i++) { try { marr.add(num++); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } }).start(); new Thread(new Runnable() { public void run() { for(int i=0; i<30; i++) try { System.out.println(marr.get()); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } }).start(); } }
原文地址:http://blog.csdn.net/u014600432/article/details/41512887