黑马程序员 多线程

来源:互联网 发布:网络司法拍卖变卖 编辑:程序博客网 时间:2024/06/12 20:42

 ------- android培训、java培训、期待与您交流! ----------

 

进程:是一个正在执行的程序。每一个进程执行都有一个执行顺序,该顺序就是一个执行路径,或者叫一个控制单元。

线程:就是进程中的一个独立的控制单元,线程在控制着进程。

创建线程的步骤:

1.定义类继承Thread。

2.覆写Thread类中的run方法。

3.调用线程的start方法,该方法有两个作用:一,启动线程。二,调用run方法。

例:

d.start()//开启线程并执行run方法。

d.run()//仅仅是对象调用方法,创建了线程却没有执行。

static Thread carrentThread()//获取当前线程对象。

getName()//获取线程名称。

设置线程名称setName或者构造函数:

class Test extends Thread{//private String name;Test(String name){//this.name = name;super(name);}public void run(){for(int x=0; x<60; x++){System.out.println((Thread.currentThread()==this)+"..."+this.getName()+" run..."+x);}}}class ThreadTest {public static void main(String[] args) {Test t1 = new Test("one---");Test t2 = new Test("two+++");t1.start();t2.start();//t1.run();//t2.run();for(int x=0; x<60; x++){System.out.println("main....."+x);}}}

第二种方式:

实现Runnable接口,通过Thread的构造方法接受实现了Runnable的实际对象。

具体步骤:

1.定义类实现Runnable接口。

2.覆盖Runnable接口中德run方法。

3.通过Thread类建立线程对象。

4.将Runnable接口的字类对象作为实际参数传递给Thread雷的构造函数。

5.调用Thread类的start方法开启线程并调用Runnable接口子类的run方法。

实现方式和继承方式有什么区别呢?

实现方式好处:避免了单继承的局限性。
在定义线程时,建立使用实现方式。

两种方式区别:

继承Thread:线程代码存放Thread子类run方法中。
实现Runnable,线程代码存在接口的子类的run方法。

 上例的另一种实现方式:

class Ticket implements Runnable//extends Thread{private  int tick = 100;public void run(){while(true){if(tick>0){System.out.println(Thread.currentThread().getName()+"....sale : "+ tick--);}}}}class  TicketDemo{public static void main(String[] args) {Ticket t = new Ticket();Thread t1 = new Thread(t);//创建了一个线程;Thread t2 = new Thread(t);//创建了一个线程;Thread t3 = new Thread(t);//创建了一个线程;Thread t4 = new Thread(t);//创建了一个线程;t1.start();t2.start();t3.start();t4.start();}}

这里出现一个问题

当多条语句在操作同一个线程共享数据时,一个线程对多条语句只执行了一部分,还没有执行完,另一个线程参与进来执行,导致共享数据的错误。

同步代码块:

synchronized(对象){

        需要被同步的代码;

}

好处:解决了线程的安全问题。

弊端:多个线程需要判断,较消耗资源。

同步函数中,函数需要被对象调用,那么函数都有一个所属对象引用,就是this。所以同步函数使用的锁事this。

同步的两个前提:

1.两个以上线程,并把每个线程都同步(synchronized)加锁。

2.线程使用同一个所。

class Ticket implements Runnable{private  int tick = 1000;Object obj = new Object();public void run(){while(true){synchronized(this){if(tick>0){//try{Thread.sleep(10);}catch(Exception e){}System.out.println(Thread.currentThread().getName()+"....sale : "+ tick--);}}}}}class  TicketDemo2{public static void main(String[] args) {Ticket t = new Ticket();Thread t1 = new Thread(t);Thread t2 = new Thread(t);//Thread t3 = new Thread(t);//Thread t4 = new Thread(t);t1.start();t2.start();//t3.start();//t4.start();}}

同步函数的锁事this,而用静态修饰后,锁为Class。

静态进内存时,内存中没有本类对象,但是一定有该类对应的字节码文件对象:类名.class,该对象的类型是Class.

class Ticket implements Runnable{private static  int tick = 100;//Object obj = new Object();boolean flag = true;public  void run(){if(flag){while(true){synchronized(Ticket.class){if(tick>0){try{Thread.sleep(10);}catch(Exception e){}System.out.println(Thread.currentThread().getName()+"....code : "+ tick--);}}}}elsewhile(true)show();}public static synchronized void show(){if(tick>0){try{Thread.sleep(10);}catch(Exception e){}System.out.println(Thread.currentThread().getName()+"....show.... : "+ tick--);}}}class  StaticMethodDemo{public static void main(String[] args) {Ticket t = new Ticket();Thread t1 = new Thread(t);Thread t2 = new Thread(t);t1.start();try{Thread.sleep(10);}catch(Exception e){}t.flag = false;t2.start();}}

关于懒汉式程序的优化

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;}}

同步中嵌套同步会出现死锁

class Test implements Runnable{private boolean flag;Test(boolean flag){this.flag = flag;}public void run(){if(flag){while(true){synchronized(MyLock.locka){System.out.println(Thread.currentThread().getName()+"...if locka ");synchronized(MyLock.lockb){System.out.println(Thread.currentThread().getName()+"..if lockb");}}}}else{while(true){synchronized(MyLock.lockb){System.out.println(Thread.currentThread().getName()+"..else lockb");synchronized(MyLock.locka){System.out.println(Thread.currentThread().getName()+".....else locka");}}}}}}class MyLock{static Object locka = new Object();static Object lockb = new Object();}class  DeadLockTest{public static void main(String[] args) {Thread t1 = new Thread(new Test(true));Thread t2 = new Thread(new Test(false));t1.start();t2.start();}}

wait,notify(),notifyAll()都使用在同步中,因为要对持有监视器(锁)的线程操作。所以要使用在同步中,因为只有同步才具有锁。

为什么这些操作线程的方法要定义Object类中呢?

因为这些方法在操作同步中线程时,都必须要标识它们所操作线程只有的锁,只有同一个锁上的被等待线程,可以被同一个锁上notify唤醒。不可以对不同锁中的线程进行唤醒。

也就是说,等待和唤醒必须是同一个锁。

而锁可以是任意对象,所以可以被任意对象调用的方法定义Object类中。

class Res{private String name;private String sex;private boolean flag = false;public synchronized void set(String name,String sex){if(flag)try{this.wait();}catch(Exception e){}this.name = name;this.sex = sex;flag = true;this.notify();}public synchronized void out(){if(!flag)try{this.wait();}catch(Exception e){}System.out.println(name+"........"+sex);flag = false;this.notify();}}class Input implements Runnable{private Res r ;Input(Res r){this.r = r;}public void run(){int x = 0;while(true){if(x==0)r.set("mike","man");elser.set("丽丽","女女女女女");x = (x+1)%2;}}}class Output implements Runnable{private Res r ;Output(Res r){this.r = r;}public void run(){while(true){r.out();}}}class  InputOutputDemo2{public static void main(String[] args) {Res r = new Res();new Thread(new Input(r)).start();new Thread(new Output(r)).start();/*Input in = new Input(r);Output out = new Output(r);Thread t1 = new Thread(in);Thread t2 = new Thread(out);t1.start();t2.start();*/}}

生产者消费者多线程实例,运用synchronized方法:

class ProducerConsumerDemo {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();}}/*对于多个生产者和消费者。为什么要定义while判断标记。原因:让被唤醒的线程再一次判断标记。为什么定义notifyAll,因为需要唤醒对方线程。因为只用notify,容易出现只唤醒本方线程的情况。导致程序中的所有线程都等待。*/class Resource{private String name;private int count = 1;private boolean flag = false;//  t1    t2public synchronized void set(String name){while(flag)try{this.wait();}catch(Exception e){}//t1(放弃资格)  t2(获取资格)this.name = name+"--"+count++;System.out.println(Thread.currentThread().getName()+"...生产者.."+this.name);flag = true;this.notifyAll();}//  t3   t4  public synchronized void out(){while(!flag)try{wait();}catch(Exception e){}//t3(放弃资格) t4(放弃资格)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();}}}

JDK1.5 中提供了多线程升级解决方案。

将同步Synchronized替换成现实Lock操作。

将Object中的wait,notify notifyAll,替换了Condition对象。

该对象可以Lock锁 进行获取。

该示例中,实现了本方只唤醒对方操作。

Lock:替代了Synchronized
 lock
 unlock
 newCondition()

Condition:替代了Object wait notify notifyAll
 await();
 signal();
 signalAll();

生产者消费者Lock,Condition方式:

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();}}class Resource{private String name;private int count = 1;private boolean flag = false;//  t1    t2private 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();//t1,t2this.name = name+"--"+count++;System.out.println(Thread.currentThread().getName()+"...生产者.."+this.name);flag = true;condition_con.signal();}finally{lock.unlock();//释放锁的动作一定要执行。}}//  t3   t4  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){}}}}class Consumer implements Runnable{private Resource res;Consumer(Resource res){this.res = res;}public void run(){while(true){try{res.out();}catch (InterruptedException e){}}}}

 

原创粉丝点击