03-18-基础语法
19-三大不安全案例
一、买票
package threadDemo;
//线程不安全,有负数,有重叠
public class UnsafeBuyTicket {
public static void main(String[] args) {
BuyTicket station =new BuyTicket();
new Thread(station,"我").start();
new Thread(station,"你").start();
new Thread(station,"黄牛党").start();
}
}
class BuyTicket implements Runnable{
//票
private int ticketNums =10;
boolean flag =true;//外部停止方式
@Override
public void run() {
// 买票
while (flag) {
buy();
}
}
private void buy() {
//判断是否有票
if (ticketNums<=0) {
flag=false;
return;
}
//模拟延时
try {
Thread.sleep(100);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
//买票
System.out.println(Thread.currentThread().getName()+"拿到"+ticketNums--);
}
}
20-同步方法及同步块
synchronized方法:修改操作需要锁
//锁的是this
private synchronized void buy() {
//判断是否有票
不适用银行
synchronized(account){取钱操作}:建议监视共享资源,变化的对象Account。
21-CopyOnWriteArrayList
JUC-并发包,java.util.concurrent
package threadDemo;
import java.util.concurrent.CopyOnWriteArrayList;
public class TestJUC {
public static void main(String[] args) {
CopyOnWriteArrayList<String> list = new CopyOnWriteArrayList<String>();//加泛型
for (int i = 0; i < 100; i++) {
new Thread(()->{
list.add(Thread.currentThread().getName());
}).start();
}
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println(list.size());
}
}
private transient (有序)volatile (唯一) Object[] array;
22-死锁
四个必要条件
23-Lock锁
ReentrantLock:可重入锁
JDK5.0后
package threadDemo;
import java.util.concurrent.locks.ReentrantLock;
//线程不安全,有负数,有重叠
public class UnsafeBuyTicket {
public static void main(String[] args) {
BuyTicket station =new BuyTicket();
new Thread(station,"我").start();
new Thread(station,"你").start();
new Thread(station,"黄牛党").start();
}
}
class BuyTicket implements Runnable{
//票
private int ticketNums =100;
boolean flag =true;//外部停止方式
//定义Lock锁
private final ReentrantLock lock =new ReentrantLock();
@Override
public void run() {
// 买票
while (flag) {
buy();
}
}
//锁的是this
private void buy() {
try {
//判断是否有票
lock.lock();//加锁
if (ticketNums<=0) {
flag=false;
return;
}
//模拟延时
Thread.sleep(10);
//买票
System.out.println(Thread.currentThread().getName()+"拿到"+ticketNums--);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}finally {
//解锁
lock.unlock();
}
}
}
25-管程法
package threadDemo;
//利用缓冲区解决 生产者消费者模型
//生产者,消费者,产品,缓冲区
public class TestPC {
public static void main(String[] args) {
SynContainer container=new SynContainer();
new Productor(container).start();
new Consumer(container).start();
}
}
class Productor extends Thread{
SynContainer container;
public Productor(SynContainer container) {
this.container=container;
// TODO Auto-generated constructor stub
}
@Override
public void run() {
// TODO Auto-generated method stub
for (int i = 0; i < 100; i++) {
container.put(new Chicken(i));
System.out.println("放入第"+i+"只鸡");
}//没写在run内部,只有生产0-9只鸡
}
}
class Consumer extends Thread{
SynContainer container;
public Consumer(SynContainer container) {
this.container=container;
}
@Override
public void run() {
// TODO Auto-generated method stub
for (int i = 0; i < 100; i++) {
System.out.println("取出第"+container.pop().id+"只鸡");
}
}
}
class Chicken {
int id;//产品编号
public Chicken(int id) {
// TODO Auto-generated constructor stub
this.id=id;
}
}
class SynContainer{
//需要一个容器大小
public int nums=0;
Chicken[] chickens=new Chicken[10];
public synchronized void put(Chicken chicken) {
if (nums==chickens.length) {
try {
this.wait();//wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
chickens[nums]=chicken;
nums++;
this.notifyAll();
}
public synchronized Chicken pop() {
if (nums==0) {
try {
this.wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
nums--;
this.notifyAll();
return chickens[nums];//必须放最后一个?
}
}