多线程--札记
1.什么是线程和进程?两者之间的关系?
进程是程序的一次动态执行过程,线程和进程都是实现并发的基本单位。
线程是比进程更小的执行单位,一个线程可以由多个线程组成,线程消亡了,进程还在,但进程消亡了,线程一定也随之消亡。
2.线程的创建有两种方法:继承Thread类和实现Runnable接口,其中继承Thread类受java单继承局限,实现Runnable接口更具灵活性,有利于功能扩展性和线程间的数据共享,如:Student类可以继承Person类同时实现Runnable。
public class ThreadStartDemo1{public static void main(String[] args) {MyThread my1=new MyThread("one");MyThread my2=new MyThread("two");my2.setName("TWO+++"); my1.start(); my2.start(); for(int i=0;i<30;i++){System.out.println("main----"+i);}}}class MyThread extends Thread{ //private String name; public MyThread(String name){ super(name);}public void run(){for(int i=0;i<30;i++){System.out.println(Thread.currentThread().getName()+"----"+i);}}}
/*银行一个小金库,由两个客户分别存3次钱,每次存100元,统计每次客户存钱后金库总额*/ public class BankDemo{public static void main(String[] args) {Cus c=new Cus();Thread t1=new Thread(c);Thread t2=new Thread(c);t1.start();t2.start();}}/*//使用同步代码块的方法保障线程安全class Bank{private int sum=0;public void add(int n){synchronized(this){sum=sum+n;try{Thread.sleep(10);}catch (Exception e){e.printStackTrace();}System.out.println("sum="+sum);}}}*///使用同步方法保障线程安全class Bank{private int sum=0;public synchronized void add(int n){sum=sum+n;try{Thread.sleep(10);}catch (Exception e){e.printStackTrace();}System.out.println("sum="+sum);}}class Cus implements Runnable{private Bank b=new Bank();public void run(){ for(int i=0;i<3;i++){ b.add(100); // 如果在此处进行同步的话,就是要等一个客户执行自己的全部操作次数才让另外一个客户进入操作,不符合实际 }}}
public class TicketDemo{public static void main(String[] args) {MyThread my=new MyThread();Thread t1=new Thread(my);Thread t2=new Thread(my);Thread t3=new Thread(my);Thread t4=new Thread(my); t1.start(); t2.start(); t3.start(); t4.start(); }}class MyThread implements Runnable{ private /*static */ int tic=30;public void run(){for(int i=0;i<300;i++){ if(tic>0){System.out.println("sale tickets:"+tic--);}}}}
/* 同步函数用的是哪一个锁呢? 函数都要被对象调用,那么函数都有一个所属对象给引用,就是this 验证同步函数的锁就是this */ public class ThisLockDemo1{public static void main(String[] args) {MyThread my=new MyThread();Thread t1=new Thread(my);Thread t2=new Thread(my); t1.start(); try{Thread.sleep(100); }catch(Exception e){ e.printStackTrace();} my.flag=false; t2.start();}}class MyThread implements Runnable{ private int tic=30; boolean flag=true;public void run(){ //Object obj=new Object();if(flag){ while(true){ synchronized(this) //此处如果传入的参数是obj.那么输出数据将会错乱,因为多个线程间用的不是一个锁{if(tic>0) { try{Thread.sleep(100); }catch(Exception e){}System.out.println(Thread.currentThread().getName()+" sale @@@@@@:"+tic--); }}}}else{while(true){this.take();}}}public synchronized void take(){if(tic>0){ try{Thread.sleep(200); }catch(Exception e){} System.out.println(Thread.currentThread().getName()+" take ######:"+tic--); }}}
public class ThisLockDemo2{public static void main(String[] args) {MyThread my=new MyThread();Thread t1=new Thread(my);Thread t2=new Thread(my); t1.start(); try{Thread.sleep(100); }catch(Exception e){ e.printStackTrace();} my.flag=false; t2.start();}}class MyThread implements Runnable{ private static int tic=30; boolean flag=true;public void run(){ //Object obj=new Object();if(flag){ while(true){ synchronized(MyThread.class) //此处如果传入的参数是obj.那么输出数据将会错乱,因为多个线程间用的不是一个锁{if(tic>0) { try{Thread.sleep(100); }catch(Exception e){}System.out.println(Thread.currentThread().getName()+" sale @@@@@@:"+tic--); }}}}else{while(true){take();}}}public static synchronized void take()//同步方法用变为静态后,输出错误数据{if(tic>0){ try{Thread.sleep(200); }catch(Exception e){} System.out.println(Thread.currentThread().getName()+" take ######:"+tic--); }}}
//单例模式//饿汉式class Singleton{private static final Singleton s=new Singleton(); private Singleton(){} //将构造方法私有化public static Singleton getInstance(){ return s;}}//懒汉式(延迟加载)class Singleton{private static Singleton s=null; private Singleton(){} //将构造方法私有化 public static Singleton getInstance(){if(s==null){ s=new Singleton();return s;}}}//懒汉式(延迟加载)//被多线程访问时存在线程安全问题,所以可以采用同步方法//保障线程安全,但这么做的缺点是,需要对锁反复进行判断,//比较低效class Singleton{private static Singleton s=null; private Singleton(){} //将构造方法私有化 public synchronized static Singleton getInstance(){if(s==null){s=new Singleton();}return s;}}//双重判断 可以减少锁的判断 提高代码执行效率class Singleton{private static Singleton s=null; private Singleton(){} //将构造方法私有化 public static Singleton getInstance(){ if(s==null) { synchronized(Singleton.class){if(s==null){s=new Singleton();}} } return s;}}
//1.死锁是程序都在等待对方先完成,在僵持不下的情况下,就会使程序的执行处于停滞状态//2.同步的嵌套会产生死锁,过多的同步会产生死锁public class DeadLock {public static void main(String[] args) {MyLock lock1=new MyLock();MyLock lock2=new MyLock();lock1.flag=true;lock2.flag=false;Thread t1=new Thread(lock1);Thread t2=new Thread(lock2);t1.start();t2.start();}}class ZhangSan{public void say(){System.out.println("张三说你把画给我!");}public void get(){System.out.println("张三得到了画");}}class LiSi{public void say(){System.out.println("李四说你把书给我!");}public void get(){System.out.println("李四得到了书");}}class MyLock implements Runnable{boolean flag;private static ZhangSan zs=new ZhangSan();//声明static类型对象,数据共享private static LiSi ls=new LiSi();//static很重要public void run(){if(flag){ zs.say(); synchronized(zs){try{Thread.sleep(200);}catch(Exception e){}synchronized(ls){zs.get();}}}else{ ls.say(); synchronized(ls){try{Thread.sleep(200);}catch(Exception e){}synchronized(zs){ls.get();}}}}}