多线程的第一种写法:
继承 Thread类
继承 Thread类
package com.nbchina;
class Demo extends Thread{
private String demoName;
Demo(String demoName) {
this.demoName=demoName;
}
public void run(){
for(int x=0;x<60;x++)
System.out.println(demoName+" extends Thread demo run == "+x);
}
}
public class ThreadDemo {
public static void main(String[] args) {
Demo demoThread1 = new Demo("Thread1");
Demo demoThread2 = new Demo("Thread2");
demoThread1.start();
demoThread2.start();
for(int x=0;x<60;x++)
System.out.println("main Thread++"+x);
}
}
多线程的第二种写法:
继承接口Runnable
package com.nbchina; class TicketDemo implements Runnable{ private int tick=10000; public void run(){ while(true){ if(tick>0){ System.out.println(Thread.currentThread().getName()+" TicketDemo sale : "+tick--); } } } } public class ThreadDemo { public static void main(String[] args) { TicketDemo t = new TicketDemo(); Thread t1 = new Thread(t); Thread t2 = new Thread(t); t1.start(); t2.start(); } }
通过synchronized代码酷块解决安全问题.共享变量tick,通过synchronized锁住执行代码块.
package com.nbchina; class TicketDemo implements Runnable{ private int tick=10000; public void run(){ while(true){ synchronized(TicketDemo.class){ if(tick>0){ System.out.println(Thread.currentThread().getName()+" TicketDemo sale : "+tick--); } } } } } public class ThreadDemo2 { public static void main(String[] args) { TicketDemo t = new TicketDemo(); Thread t1 = new Thread(t); Thread t2 = new Thread(t); t1.start(); t2.start(); } }
通过自定义方法,附加synchronized,来解决共享变量安全问题
package com.nbchina; class TicketDemo implements Runnable{ private static int tick=10000; public void run(){ while(true){ show(); } } public static synchronized void show(){ if(tick>0){ System.out.println(Thread.currentThread().getName()+" TicketDemo2 sale : "+tick--); } } } public class ThreadDemo2 { public static void main(String[] args) { TicketDemo t = new TicketDemo(); Thread t1 = new Thread(t); Thread t2 = new Thread(t); t1.start(); t2.start(); } }
设计模式单例模式
class Single{//懒汉式 private static final Single s=new Single(); private Single(){} public static Single getInstance(){ return s; } } class Single{//恶汉式 private static Single s=null; private Single(){} public static Single getInstance(){ if(s==null){ synchronized(Single.class){ if(s==null){ s=new Single(); } } } return s; } } public class SingletonTest { public static void main(String[] arges){ Single single = Single.getInstance(); Single single2 = Single.getInstance(); System.out.print(singleton2==singleton); } }
一个资源,一个生产者一个索取者,利用synchronized函数块,以及notifyAll()、Runnable互斥。程序缺点是notifyAll()需要全部唤醒我方和对方所有等待进程。所以改进在jdk1.5。使用显示锁lock
package com.nbchina; class Resource{ private String name; private int count = 1; private boolean flag = false; public synchronized void set(String name){ while(flag)//注意:必须while 判断,不能if 。因为唤醒所有的等待进程,若当初等待进程再判断if之后等待,那么我方唤醒之后,我方等待的资源可能立即抢占互斥对方等待进程cpu的执行。因为不需要循环判断,那么就直接执行下面。 try{this.wait();}catch(Exception e){} this.name = name+":"+count++; System.out.println(Thread.currentThread().getName()+"[生产者]"+this.name); flag = true; this.notifyAll();//唤醒对方以及我方线程 } public synchronized void out(){ while(!flag) try{this.wait();}catch(Exception e){} System.out.println(Thread.currentThread().getName()+"[消费者]"+this.name); flag = false; this.notifyAll(); } } class Producer implements Runnable{ private Resource res; Producer(Resource res){ this.res=res; } public void run(){ while(true){ res.set("-商品"); } } } class Consumer implements Runnable{ private Resource res; Consumer(Resource res){ this.res=res; } public void run(){ while(true){ res.out(); } } } public class ThreadDemo4 { public static void main(String[] args) { Resource r = new Resource(); Producer pro = new Producer(r); Consumer con = new Consumer(r); Thread t1 = new Thread(pro); Thread t2 = new Thread(con); t1.start(); t2.start(); } }
互斥使用资源,利用jdk1.5中的lock解决方案。
package com.nbchina; import java.util.concurrent.locks.Condition; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock; /** * jdk1.5提供了多线程升级解决方案.将同步Synchronized替换成Lock操作. * 将Object中的wait,notify notifyAll换成Condition对象. */ class Resource{ private String name; private int count = 1; private boolean flag = false; private Lock lock =new ReentrantLock(); private Condition condition_pro = lock.newCondition(); private Condition condition_con = lock.newCondition(); public void set(String name) throws InterruptedException{ lock.lock(); try{ while(flag) condition_pro.await(); this.name = name+":"+count++; System.out.println(Thread.currentThread().getName()+"[生产者]"+this.name); flag = true; condition_con.signal(); }finally{ lock.unlock(); } } public void out() throws InterruptedException{ lock.lock(); try{ while(!flag) condition_con.await(); System.out.println(Thread.currentThread().getName()+"[消费者]"+this.name); flag = false; condition_pro.signal(); }finally{ lock.unlock(); } } } class Producer implements Runnable{ private Resource res; Producer(Resource res){ this.res=res; } public void run(){ while(true){ try { res.set("-商品"); } catch (InterruptedException e) { e.printStackTrace(); } } } } class Consumer implements Runnable{ private Resource res; Consumer(Resource res){ this.res=res; } public void run(){ while(true){ try { res.out(); } catch (InterruptedException e) { e.printStackTrace(); } } } } public class ThreadDemo5 { public static void main(String[] args) { Resource r = new Resource(); Producer pro = new Producer(r); Consumer con = new Consumer(r); Thread t1 = new Thread(pro); Thread t2 = new Thread(con); t1.start(); t2.start(); } }