day11多线程,run方法。卖票多线程示例。synchronized,同步锁对象,回顾单例。死锁问题

来源:互联网 发布:穿越火线找不到优化 编辑:程序博客网 时间:2024/05/16 14:48
/*多线程,run方法。卖票多线程示例。synchronized,同步锁对象,回顾单例。死锁问题*/多线程进程和线程的区别。每一个正在执行的程序叫进程,一个进程里至少有一个线程。多线程存在的意义:让程序同时执行多线程的创建方式:第一:就是继承Thread类1.定义类继承Thread.2.覆盖run方法。public void run()3.创建对象。new Demo();4.调用线程的start()方法。该方法有二个作用。class Demo extends Thread{public void run(){for(int x=0;x<60;x++){System.out.println("Demo run"+x);}}}class ThreadDemo{public static void main(String[] args){Demo d = new Demo();d.start();for(int x=0;x<60;x++){System.out.println("main run"+x);}}}为什么要覆盖run方法?Thread用于描述线程。该类定义了一个功能,用于存储线程要运行的代码,该存储功能就是run方法。也就是说,Thread 类中的run方法,用于存储线程要运行的代码。Thread t = new Thread();t.start();//要覆盖run方法才有意义。线程运行的几种状态被创建,运行,冻结,消亡状态,阻塞状态。


线程都有自己默认的名字。从0开始,getName()获取。通过构造方法super(String name)可以设置。Thread.currentThread().getName()===this.getName();currentThread():获取当前线程对象,静态的,通过getName():获取线程名字。设置线程名字:setName()或者构造函数。super();class Ticket extends Thread{private static  int tick = 100;//静态可以解决共享数据public void run(){while (true){if (tick>0){System.out.println(currentThread().getName()+"sale:"+tick--);}}}}class TicketDemo{public static void main(String[] args){Tictet t1 = new Tictet();Tictet t2 = new Tictet();Tictet t3 = new Tictet();Tictet t4 = new Tictet();t1.start();t2.start();t3.start();t4.start();}}创建线程的第二种方式,1实现一个Runnable接口。2覆写run()方法。3.通过Thread类创建线程对象。4.把实现接口的类对象作为参数传给Thread();5.通过Thread类,开启start()。class Demo implements Runnable{public void run(){}}new Thread(new Demo()).start();//卖票程序class Ticket implements Runnable//extends Thread{private int tick = 100;//静态可以解决共享数据public void run(){while (true){if (tick>0){System.out.println(currentThread().getName()+"sale:"+tick--);}}}}class TicketDemo{public static void main(String[] args){Tictet t = new Ticket();new Thread(t).start();new Thread(t).start();new Thread(t).start();new Thread(t).start();}}实现方式和继承方式有什么区别?继承具有局限性,因为java是单继承,继承了Thread类就不能继承别的类。实现方式的好处在于避免了单继承的局限性,建议使用实现方式。多线程的安全问题:卖票当1>0时,此线程等待,其他线程过来,然后再判断1>0,执行完后,然后此线程再减减,会出现负数情况。当多条语句在操作同一个线程共享数据时,一个线程对多条语句只执行一部分还没有执行完,另一个线程参与进来,导致共享数据的错误。解决办法 :对多条操作共享数据的语句,只能让一个线程执行完,在执行过程中,其他线程不可以参与执行。java对于多线程的安全问题,提供了专业的解决方式。同步代码块。synchronized(对象){需要被同步的代码}//这个对象:你想放哪个就放哪个。只要是对象就行。synchronized(对象){while (true){if (tick>0){System.out.println(currentThread().getName()+"sale:"+tick--);}}}同步的二个前提:1.必须要有两个或者两个以上的线程。2.必须是多个线程使用同一个锁。保证同步中只能有一个线程在运行。好处:解决了多线程的安全问题弊端:多个线程需要判断锁,较为消耗资源。把 synchronized 作为修饰符放在函数上,让函数具有同步性。同步函数用的锁是:方法是被对象调用,前面省略this.方法名();所以同步函数使用的锁的是:this.静态同步函数的锁是所在类的Class对象。类名.class静态进内存时,内存中没有本类对象,但是一定有该类对应的字节码文件对象。class Ticket implements Runnable//extends Thread{private int tick = 100;boolean flag = true;public void run(){if(flag){while (true){synchronized(this)//synchronized(Ticket.class){if (tick>0){System.out.println(currentThread().getName()+"sale:"+tick--);}}}}else{while(true)method();}}public synchronized void method()//this//public static synchronized void method()//Ticket.class//方法静态,tick也要为静态。{if (tick>0){System.out.println(currentThread().getName()+"method:"+tick--);}}}class TicketDemo{public static void main(String[] args){Tictet t = new Ticket();new Thread(t).start();t.flag = false;//变动条件new Thread(t).start();}}回顾单例设计模式:饿汉式:class Single{private Single(){}private static Single s = new Single();public static Single getInstance(){return s;}}//双重判断的安全的懒汉式class Single{private Single(){}private static Single s = null;public static Single getInstance(){if(s == null){synchronized(Single.class){if (s == null){s = new Single();}}}return s;}}多线程:死锁问题。同步中嵌套同步,但是锁不同。class Ticket implements Runnable//extends Thread{private int tick = 100;boolean flag = true;Object obj  = new Object();public void run(){if(flag){while (true){synchronized(obj){method();}}}else{while(true)method();}}public synchronized void method()//this{synchronized(obj){if (tick>0){System.out.println(currentThread().getName()+"method:"+tick--);}}}}class DeadLockDemo{public static void main(String[] args){Tictet t = new Ticket();new Thread(t).start();t.flag = false;//变动条件new Thread(t).start();}}//--------------------------------------------------------//以下是人造一个死锁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("if locka");synchronized(MyLock.lockb){System.out.println("if lockb");}}}else{synchronized(MyLock.lockb){System.out.println("else lockb");synchronized(MyLock.locka){System.out.println("else locka");}}}}}class MyLock{static MyLock locka = new MyLock();//老师视频上用Objectstatic MyLock lockb = new MyLock();}class DeadLockTest{public static void main(String[] args){new Thread(new Test(true)).start();new Thread(new Test(false)).start();}}

原创粉丝点击