前言:
在面向对象的思想下,线程的写法根据要创建的对象层级可以分为三种写法:
1,一层对象写法:采用extends Thread,复写父类的run()方法,直接建立一个线程实例对象的方式,这种方式简单,适用于单任务的单线程需求.在此不做过多讨论;
2,二层对象写法:采用implements Runnable接口,复写接口的run()方法,得到二级对象--通常称为任务对象;再通过将二级对象传入(负责main()方法的)一级对象的new Thread()构造参数,一级对象采用多态的Thread引用到run()方法;
import java.util.Random;
//两个线程一起买票的例子:
class FinalDemo1 implements Runnable {
private int[] arr = new int[6];
private int n=0;
// private int num = 50;
public void run() {
for (int i = 0; i < 100; i++) {
synchronized(this){
if (/*num > 0 &&*/ n<6) {
try {
Thread.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
// System.out.println(Thread.currentThread().getName() + "卖出了第"
// + num-- + "张票!");
arr[n]= new Random().nextInt(10);n++;
for(int a:arr){System.out.print(a);}
System.out.println();
}
}
}
}
}
public class MyThreadDemo2 {
public static void main(String[] args) {
FinalDemo1 f = new FinalDemo1();
new Thread(f, "A").start();
new Thread(f, "B").start();
new Thread(f, "C").start();
}
}
二层写法要注意:共享的资源一般写在私有属性上,因此建立线程时,不能new多个Runnable! 否则就是多线程执行多个相同的任务了;应该先new一个Runnable对象r,始终将这个对象传给多个new Thread(r)就行了.
3,三层对象写法:在二层写法的基础上,因为任务的复杂度,建立第三个对象--通常称为resource资源对象来负责建立不同的处理方法,常见的是一个生产式方法,一个消费式方法,或者要交替执行的两个其它方法;
因为资源是唯一的,有要共享的属性,所以更严谨的可以写成单例;如此,new Thread(new Runnable(res))形成三层对象完成一个线程的定义,并且多个任务的多个线程,都共同操作着一个res,为保证安全,只需对res中的方法进行同步就欧了;
举两个例子:
一个任务,多个线程的例子: 虽然可以用二层对象写法,但是抽出第三层资源对象后,可以对线程任务更好控制,如交替执行;
//两个线程填充一个数组问题: import java.util.Random; public class Test { /* * 声明一个共享数组,起两个线程,两个线程分别隔一段时间(可以写一个随机数), * 给数组中添加数据,每一个线程为数组添加3个数据即可。
*
*/
public static void main(String[] args) {
final ShareArr sharearr = ShareArr.getInstance();
new Thread(new Runnable()
{
public void run()
{
for(int i = 0;i<3;i++)
{
sharearr.addNumFirst();
}
}
}).start();
//因为使用了三级设计,对资源的调用同一个对象,因此不同的方法仍然共享private的属性,因此两个线程的第"i+1"个元素可以同步;
new Thread(new Runnable()
{
public void run()
{
for(int i = 0;i<3;i++)
{
sharearr.addNumSecond();
}
}
}).start();
}
}
class ShareArr
{
private ShareArr(){};
private static ShareArr arr = null;
public static ShareArr getInstance()
{
if(arr == null)
{
synchronized (ShareArr.class)
{
if(arr == null)
{
arr = new ShareArr();
}
}
}
return arr;
}
private int[] array = new int[6];
private int i = 0;
boolean flag = true;
public synchronized void addNumFirst()
{
while(!flag)
{
try {
this.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
int num = new Random().nextInt();
System.out.println(Thread.currentThread().getName()+"给数组第"+(i+1)+"个元素赋值"+num);
array[i++] = num;
flag = false;
this.notify();
}
public synchronized void addNumSecond()
{
while(flag)
{
try {
this.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
int num = new Random().nextInt();
System.out.println(Thread.currentThread().getName()+"给数组第"+(i+1)+"个元素赋值"+num);
array[i++] = num;
flag = true;
this.notify();
}
}
多任务,多线程的例子: 一般都得采用三层对象写法;
生产&消费的synchronized和lock方式例子:
ProducerConsumerDemo
class ProducerConsumerDemo2
{
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 (pro);
Thread t3=new Thread (con);
Thread t4=new Thread (con);
t1.start();
t2.start();
t3.start();
t4.start();
System.out.println("Hello World!");
}
}
class Resource
{
private String name;
private int count=1;
private boolean flag=false;
public synchronized void set(String name)
{
while(flag)
try{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{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();
}
}
}
import java.util.concurrent.locks.*;
class ProducerConsumerDemo2
{
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 (pro);
Thread t3=new Thread (con);
Thread t4=new Thread (con);
t1.start();
t2.start();
t3.start();
t4.start();
System.out.println("Hello World!");
}
}
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();//condition的抛异wait常方法,把pro的线程停止.
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();//try{wait();}catch(Exception e){}
System.out.println(Thread.currentThread().getName()+"...消费者......"+this.name);
flag=false;
condition_pro.signal();//this.notifyAll();唤醒all
}
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)
{
}
}
}
}
class Consumer implements Runnable
{
private Resource res;
Consumer(Resource res)
{
this.res=res;
}
public void run()
{
while(true)
{
try
{
res.out();
}
catch (InterruptedException e)
{
}
}
}
}