* 程序只要有一个非后台(守护)的线程在运行,就不会结束。
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