黑马程序员 多线程
来源:互联网 发布:网络司法拍卖变卖 编辑:程序博客网 时间: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){}}}}
- 黑马程序员 多线程
- 黑马程序员:多线程
- 黑马程序员-java多线程
- 黑马程序员--java 多线程
- 黑马程序员_java多线程
- 黑马程序员-java多线程
- 黑马程序员_多线程
- 黑马程序员 多线程
- 黑马程序员_JAVA多线程
- 黑马程序员—多线程
- 黑马程序员- 多线程
- 黑马程序员_多线程
- 黑马程序员--多线程
- 黑马程序员_多线程
- 黑马程序员--Java多线程
- 黑马程序员---多线程
- 黑马程序员__多线程
- 黑马程序员_多线程
- c#代码规范
- SQL命令大全
- VC 模式对话框和非模式对话框的创建,销毁和区别
- Android Fragment完全解析,关于碎片你所需知道的一切
- PL/SQL监听失败
- 黑马程序员 多线程
- smarty显示部分文字,其余鼠标放置时显示全部
- C#调用C++的DLL数据类型转换方式
- 第一步
- sqlserver 时间格式化
- 安卓开发-Sqliteopenhelper使用
- 文件下载代码
- 网站群建设-->营造自己的网络圈品牌
- SQL SERVER PIVOT使用