1 多线程的两种方式
① 创建一个类,继承Thread,重写run方法,
public class MyThread extends Thread { @Override public void run() { for(int i=0;i <=200;i++){ System.out.println(i+getName()); } } } public class Demo1 { public static void main(String[] args) { MyThread myThread1 = new MyThread(); MyThread myThread2 = new MyThread(); myThread1.start(); myThread2.start(); } }
② 创建一个类,实现Runnable接口,重写run方法,
public class MyThread2 implements Runnable{ @Override public void run() { for(int i = 1;i<=100;i++){ System.out.println(i+Thread.currentThread().getName()); } } } public class Demo2 { public static void main(String[] args) { MyThread2 mt2 = new MyThread2(); Thread th2 = new Thread(mt2); Thread th3 = new Thread(th2); th2.start(); th3.start(); } }
2 线程安全
① 发生线程安全的条件
1 . 是否有共享数据
2 . 是否是多线程
3 . 是否对同一数据进行操作
② 线程锁案例
1 创建自定义线程类,模拟去电影院购买电影票。
public class MyThread3 implements Runnable{ private int ticket = 100; @Override public void run() { // TODO Auto-generated method stub while(true){ if(ticket>0){ try { Thread.sleep(100); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } System.out.println(Thread.currentThread().getName() + "正在出售第" + (ticket--) + "张票 "); } } } }
创建相应的测试类
public class Demo3 { public static void main(String[] args) { MyThread3 thread3 = new MyThread3(); Thread t1 = new Thread(thread3, "1号"); Thread t2 = new Thread(thread3, "2号"); Thread t3 = new Thread(thread3, "3号"); t1.start(); t2.start(); t3.start(); } }
2号正在出售第100张票 1号正在出售第99张票 3号正在出售第100张票 1号正在出售第98张票 3号正在出售第98张票 2号正在出售第98张票 3号正在出售第96张票 1号正在出售第97张票 2号正在出售第97张票 3号正在出售第95张票 1号正在出售第95张票 2号正在出售第95张票 1号正在出售第94张票 3号正在出售第94张票 2号正在出售第94张票 2号正在出售第92张票 1号正在出售第93张票 3号正在出售第92张票 2号正在出售第90张票 3号正在出售第91张票 1号正在出售第91张票 2号正在出售第89张票 1号正在出售第87张票 3号正在出售第88张票 2号正在出售第86张票 1号正在出售第86张票 3号正在出售第86张票 1号正在出售第84张票 2号正在出售第85张票 3号正在出售第84张票 3号正在出售第83张票 1号正在出售第83张票 2号正在出售第83张票 1号正在出售第82张票 2号正在出售第81张票 3号正在出售第80张票 3号正在出售第79张票 1号正在出售第78张票 2号正在出售第79张票 3号正在出售第77张票 2号正在出售第76张票 1号正在出售第76张票 3号正在出售第75张票 2号正在出售第75张票 1号正在出售第75张票 3号正在出售第74张票 1号正在出售第72张票 2号正在出售第73张票 2号正在出售第71张票 3号正在出售第70张票 1号正在出售第71张票 3号正在出售第69张票 1号正在出售第69张票 2号正在出售第69张票 2号正在出售第68张票 3号正在出售第67张票 1号正在出售第67张票 2号正在出售第66张票 3号正在出售第66张票 1号正在出售第66张票 3号正在出售第65张票 1号正在出售第65张票 2号正在出售第64张票 1号正在出售第63张票 2号正在出售第61张票 3号正在出售第62张票 1号正在出售第60张票 2号正在出售第58张票 3号正在出售第59张票 3号正在出售第57张票 2号正在出售第56张票 1号正在出售第57张票 3号正在出售第55张票 1号正在出售第54张票 2号正在出售第55张票 2号正在出售第53张票 1号正在出售第51张票 3号正在出售第52张票 2号正在出售第49张票 3号正在出售第50张票 1号正在出售第49张票 3号正在出售第48张票 1号正在出售第47张票 2号正在出售第46张票 3号正在出售第45张票 2号正在出售第43张票 1号正在出售第44张票 3号正在出售第42张票 1号正在出售第40张票 2号正在出售第41张票 3号正在出售第39张票 2号正在出售第38张票 1号正在出售第37张票 3号正在出售第36张票 2号正在出售第35张票 1号正在出售第36张票 2号正在出售第34张票 1号正在出售第32张票 3号正在出售第33张票 3号正在出售第31张票 1号正在出售第29张票 2号正在出售第30张票 2号正在出售第28张票 3号正在出售第27张票 1号正在出售第26张票 3号正在出售第25张票 2号正在出售第23张票 1号正在出售第24张票 2号正在出售第21张票 3号正在出售第20张票 1号正在出售第22张票 3号正在出售第18张票 2号正在出售第18张票 1号正在出售第19张票 3号正在出售第17张票 2号正在出售第16张票 1号正在出售第16张票 3号正在出售第15张票 2号正在出售第15张票 1号正在出售第15张票 1号正在出售第12张票 3号正在出售第14张票 2号正在出售第13张票 3号正在出售第11张票 1号正在出售第10张票 2号正在出售第10张票 3号正在出售第9张票 1号正在出售第9张票 2号正在出售第9张票 1号正在出售第8张票 3号正在出售第8张票 2号正在出售第8张票 1号正在出售第7张票 2号正在出售第7张票 3号正在出售第7张票 3号正在出售第6张票 2号正在出售第6张票 1号正在出售第6张票 3号正在出售第3张票 2号正在出售第5张票 1号正在出售第4张票 3号正在出售第2张票 2号正在出售第2张票 1号正在出售第2张票 2号正在出售第1张票 3号正在出售第1张票 1号正在出售第1张票
通过控制台,我们可以看出打印的有问题,票有很多重复了。就是因为多线程的原因,分析一下原因,当1 号刚进来的时候,执行了--ticket的时候,这个时候,线程2进来了,所以出现了很多都在出卖同一张票的原因,下面说一下解决方案
public class MyThread3 implements Runnable{ private int ticket = 100; private Object object = new Object(); @Override public void run() { // TODO Auto-generated method stub while(true){ synchronized (object) { if(ticket>0){ try { Thread.sleep(200); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } System.out.println(Thread.currentThread().getName() + "正在出售第" + (ticket--) + "张票 "); } } } } }
我在主要的代码段上添加锁的机制,
synchronized (object)
里面传递的参数是任意的,这个时候,当线程1进入的时候,会给cpu上一把锁,其他的线程不能进入,只有当线程1离开的时候,其他的线程才能进来。运行之后,我们查看控制台
3号正在出售第100张票 3号正在出售第99张票 3号正在出售第98张票 3号正在出售第97张票 3号正在出售第96张票 3号正在出售第95张票 3号正在出售第94张票 2号正在出售第93张票 2号正在出售第92张票 1号正在出售第91张票 2号正在出售第90张票 2号正在出售第89张票 3号正在出售第88张票 2号正在出售第87张票 1号正在出售第86张票 2号正在出售第85张票 2号正在出售第84张票 2号正在出售第83张票 2号正在出售第82张票 2号正在出售第81张票 2号正在出售第80张票 2号正在出售第79张票 2号正在出售第78张票 2号正在出售第77张票 2号正在出售第76张票 2号正在出售第75张票 2号正在出售第74张票 2号正在出售第73张票 2号正在出售第72张票 2号正在出售第71张票 2号正在出售第70张票 2号正在出售第69张票 2号正在出售第68张票 2号正在出售第67张票 3号正在出售第66张票 3号正在出售第65张票 3号正在出售第64张票 3号正在出售第63张票 2号正在出售第62张票 2号正在出售第61张票 1号正在出售第60张票 2号正在出售第59张票 3号正在出售第58张票 3号正在出售第57张票 3号正在出售第56张票 3号正在出售第55张票 3号正在出售第54张票 3号正在出售第53张票 3号正在出售第52张票 3号正在出售第51张票 3号正在出售第50张票 2号正在出售第49张票 1号正在出售第48张票 2号正在出售第47张票 2号正在出售第46张票 2号正在出售第45张票 2号正在出售第44张票 3号正在出售第43张票 2号正在出售第42张票 1号正在出售第41张票 2号正在出售第40张票 2号正在出售第39张票 2号正在出售第38张票 3号正在出售第37张票 2号正在出售第36张票 2号正在出售第35张票 1号正在出售第34张票 2号正在出售第33张票 3号正在出售第32张票 3号正在出售第31张票 3号正在出售第30张票 3号正在出售第29张票 3号正在出售第28张票 3号正在出售第27张票 2号正在出售第26张票 1号正在出售第25张票 1号正在出售第24张票 2号正在出售第23张票 2号正在出售第22张票 2号正在出售第21张票 3号正在出售第20张票 2号正在出售第19张票 2号正在出售第18张票 2号正在出售第17张票 1号正在出售第16张票 1号正在出售第15张票 2号正在出售第14张票 2号正在出售第13张票 2号正在出售第12张票 2号正在出售第11张票 2号正在出售第10张票 2号正在出售第9张票 3号正在出售第8张票 3号正在出售第7张票 2号正在出售第6张票 1号正在出售第5张票 1号正在出售第4张票 2号正在出售第3张票 2号正在出售第2张票 3号正在出售第1张票