多线程 并发 同步 性能分析
/**
* 线程安全: 在并发时保证数据的正确性、效率尽可能高
* synchronized
* 1、同步方法
* 2、同步块
* @author Administrator
*
*/
public class SynBlockTest03 {
public static void main(String[] args) {
//一份资源
SynWeb12306 web =new SynWeb12306();
//多个代理
new Thread(web,"码畜").start();
new Thread(web,"码农").start();
new Thread(web,"码蟥").start();;
}
}
class SynWeb12306 implements Runnable{
//票数
private int ticketNums =10;
private boolean flag = true;
@Override
public void run() {
while(flag) {
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
test5();
}
}
//线程安全:尽可能锁定合理的范围(不是指代码 指数据的完整性)
//double checking
public void test5() {
if(ticketNums<=0) {//考虑的是没有票的情况
flag = false;
return ;
}
synchronized(this) {
if(ticketNums<=0) {//考虑最后的1张票
flag = false;
return ;
}
//模拟延时
try {
Thread.sleep(200);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName()+"-->"+ticketNums--);
}
}
//线程不安全 范围太小锁不住
public void test4() {
synchronized(this) {
if(ticketNums<=0) {
flag = false;
return ;
}
}
//模拟延时
try {
Thread.sleep(200);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName()+"-->"+ticketNums--);
}
//线程不安全 ticketNums对象在变 锁的应该是地址,锁的应该是不变的东西
public void test3() {
synchronized((Integer)ticketNums) {
if(ticketNums<=0) {
flag = false;
return ;
}
//模拟延时
try {
Thread.sleep(200);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName()+"-->"+ticketNums--);
}
}
//线程安全 范围太大 -->效率低下
public void test2() {
//用this没有问题,因为把对象给锁定啦! 要锁ticketNums和flag 这两个变量,只有这两个锁住啦,才是真的锁住啦
synchronized(this) {
if(ticketNums<=0) {
flag = false;
return ;
}
//模拟延时
try {
Thread.sleep(200);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName()+"-->"+ticketNums--);
}
}
//线程安全 同步
public synchronized void test1() {
if(ticketNums<=0) {
flag = false;
return ;
}
//模拟延时
try {
Thread.sleep(200);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName()+"-->"+ticketNums--);
}
}
快乐影院 订票操作
/**
* 快乐影院
* @author Administrator
*
*/
public class HappyCinema {
public static void main(String[] args) {
Cinema c=new Cinema(1,"happy dym");
new Thread(new Customer(c, 2),"止兮").start();
new Thread(new Customer(c, 1),"苍凌").start();
}
}
//顾客
class Customer implements Runnable{
Cinema cinema;
int seats;
public Customer(Cinema cinema, int seats) {
super();
this.cinema = cinema;
this.seats = seats;
}
@Override
public void run() {
synchronized(cinema) {
boolean flag=cinema.bookTickets(seats);
if(flag) {
System.out.println("出票成功"+Thread.currentThread().getName()+"->票数为:"+seats);
}else {
System.out.println("出票失败"+Thread.currentThread().getName()+"->位置不够");
}
}
}
}
//影院
class Cinema{
int available; //可用的位置个数
String name; //名称
public Cinema(int available, String name) {
super();
this.available = available;
this.name = name;
}
//购票
public boolean bookTickets(int seats) {
System.out.println("可用的位置个数为:"+available);
if(seats>available) {
return false;
}
available -= seats;
return true;
}
}
快乐影院 订票操作 改良版
import java.util.ArrayList;
import java.util.List;
/**
* 快乐影院
* @author Administrator
*
*/
public class HappyCinema2 {
public static void main(String[] args) {
//可用位置
List<Integer> available=new ArrayList<Integer>();
available.add(1);
available.add(3);
available.add(4);
available.add(5);
available.add(6);
available.add(9);
//顾客需要的位置
List<Integer> seat1=new ArrayList<Integer>();
seat1.add(1);
seat1.add(2);
List<Integer> seat2=new ArrayList<Integer>();
seat2.add(3);
seat2.add(5);
seat2.add(9);
DymCinema d=new DymCinema(available, "happy dym");
new Thread(new HappyCustomer(d, seat1),"止兮").start();
new Thread(new HappyCustomer(d, seat2),"苍凌").start();
}
}
//顾客
class HappyCustomer implements Runnable{
DymCinema cinema;
List<Integer> seats;
public HappyCustomer(DymCinema cinema, List<Integer> seats) {
this.cinema = cinema;
this.seats = seats;
}
@Override
public void run() {
synchronized(cinema) {
boolean flag=cinema.bookTickets(seats);
if(flag) {
System.out.println("出票成功"+Thread.currentThread().getName()+"-<位置为:"+seats);
}else {
System.out.println("出票失败"+Thread.currentThread().getName()+"-<位置不够");
}
}
}
}
//影院
class DymCinema{
List<Integer> available; //可用的位置
String name; //名称
public DymCinema(List<Integer> available, String name) {
this.available = available;
this.name = name;
}
//购票
public boolean bookTickets(List<Integer> seats) {
System.out.println("欢迎光临"+this.name+",当前的可用位置为:"+available);
List<Integer> copy=new ArrayList<Integer>();
copy.addAll(available);
//相减
copy.removeAll(seats);
//判断大小
if(available.size()-copy.size()!=seats.size()) {
return false;
}
//订票成功
available=copy;
return true;
}
}
快乐火车票
/**
* 快乐火车票
* @author Administrator
*
*/
public class Happy12306 {
public static void main(String[] args) {
Web12306 c=new Web12306(4,"happy dym");
new Passenger(c,"止兮",2).start();
new Passenger(c,"苍凌",1).start();
}
}
//顾客
class Passenger extends Thread{
int seats;
public Passenger(Runnable target,String name,int seats) {
super(target,name);
this.seats=seats;
}
}
// 火车票网
class Web12306 implements Runnable{
int available;//可用的位置
String name; //名称
public Web12306(int available, String name) {
this.available = available;
this.name = name;
}
@Override
public void run() {
Passenger p=(Passenger)Thread.currentThread();
boolean flag=this.bookTickests(p.seats);
if(flag) {
System.out.println("出票成功"+Thread.currentThread().getName()+"->订位置的个数:"+p.seats);
}else {
System.out.println("出票失败"+Thread.currentThread().getName()+"->位置不够");
}
}
//购票
public synchronized boolean bookTickests(int seats) {
System.out.println("可用位置个数为"+available);
if(seats>available) {
return false;
}
available -= seats;
return true;
}
}
操作并发容器
import java.util.concurrent.CopyOnWriteArrayList;
/**
* 线程安全:操作并发容器
* @author Administrator
*
*/
public class SynContainer {
public static void main(String[] args) throws InterruptedException {
CopyOnWriteArrayList<String> list=new CopyOnWriteArrayList<String> ();
for(int i=0;i<10000;i++) {
new Thread(()->{
list.add(Thread.currentThread().getName());
}) .start();
}
Thread.sleep(1000);
System.out.println(list.size());
}
}