1.死锁,多个线程互相抱着对方的资源,形成僵持 (口红和镜子的例子)
解决方法: 不要在锁中加锁,不用同一把锁
2.Lock锁(显式定义同步锁对象)(只能锁代码块,性能好[较少时间调度线程],拓展性强)
1.ReentrantLock可重入锁
private final ReentrantLock =new ReentrantLock();
try{
lock.lock();
}finnally{
lock.unlock();
}
使用顺序 Lock>同步代码块>同步方法
public class LockTicket {
public static void main(String[] args) {
Sell sell = new Sell();
new Thread(sell,"a1").start();
new Thread(sell,"a2").start();
}
}
class Sell implements Runnable{
int ticket=100;
private final ReentrantLock lock=new ReentrantLock();
Sell(){
}
@Override
public void run() {
while(true){
if(ticket>0){
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
lock.lock();
System.out.println("线程"+Thread.currentThread().getName()+"抢到了"+ticket--);
lock.unlock();
}
}
}
}
}
3.线程协作 生产者消费者问题(都是使用synchronized方法单独创建生产者和消费者)
使用wait()和notifyAll() 方法
wait()只能通过notify唤醒,
notify唤醒的是第一个进入等待的线程,先进先出队列
notifyAll()唤醒所有线程我,最后进入等待的线程最先被唤醒:后进先出 栈
- 并发协作模型----管程法(消费者不能直接拿到生产者的信息,需要缓冲区,加锁拿,生产者和消费者分别写)
public class ManageThreadWay {
public static void main(String[] args) {
Container container = new Container();
new Customer(container).start();
new Producer(container).start();
}
}
class Producer extends Thread{
Container container;
Producer(Container container){
this.container=container;
}
@Override
public void run() {
for (int i = 0; i < 100; i++) {
try {
System.out.println("生产了第"+i+"只鸡");
container.push(new Chicken(i));
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
class Customer extends Thread{
Container container;
Customer(Container container){
this.container=container;
}
@Override
public void run() {
for (int i = 0; i < 100; i++) {
System.out.println("消费了第"+i+"只鸡");
try {
container.pop();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
class Container{
Chicken[] chickens=new Chicken[10];
int count=0;
Container(){
}
//出栈
public synchronized Chicken pop() throws InterruptedException {
if (count==0){
this.wait();
}
System.out.println("消费"+count);
count--;
Chicken chicken=chickens[count];
this.notifyAll();
return chicken;
}
//入栈
public synchronized void push(Chicken chicken) throws InterruptedException {
//如果栈满,则等待消费
if(count == chickens.length){
this.wait();
}
System.out.println("生产"+count);
chickens[count]=chicken;
count++;
this.notifyAll();
}
}
class Chicken {
int id;
String name;
Chicken(){
}
Chicken(int id){
this.id=id;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
- 并发协作模型----信号灯法(true和false)红灯停绿灯行 ,生产者如果true生产后唤醒线程,如果false等待
public class LightWay {
public static void main(String[] args) {
Container1 container1 = new Container1();
new Producer1(container1).start();
new Customer1(container1).start();
}
}
class Producer1 extends Thread{
Container1 container1;
Producer1(Container1 container1){
this.container1=container1;
}
@Override
public void run() {
for (int i = 0; i < 100; i++) {
container1.set(i+"");
}
}
}
class Customer1 extends Thread{
Container1 container1;
Customer1(Container1 container1){
this.container1=container1;
}
@Override
public void run() {
for (int i = 0; i < 100; i++) {
try {
container1.get();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
class Container1{
boolean flag=true; //代表是否可以消费
String thing="";
public synchronized void set(String thing) {
if(!flag){
try {
this.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println("生产了"+thing);
this.thing=thing;
this.flag=!flag;
this.notifyAll();
}
public synchronized void get() throws InterruptedException {
if(flag){
this.wait();
}
System.out.println("消费了"+thing);
this.flag=!flag;
this.notifyAll();
}
}
4.线程池(提前创建线程,不用一直创建和销毁导致性能消耗,重复利用资源)
- 好处: 通过响应速度 减低资源消耗 便于线程管理
(设置池大小corePoolSize,最大线程数maxiumPoolSize,没有任务多久关闭线程KeepAliveTime)- 线程池类 Excutor和ExecutorService 和Callable使用一样
ExecutorService service=Executors.newFixedThreadPool(10);//线程池大小,不能设置太多,可能有有异常产生…
service.execute(new xxMyThread());//实现了Runnable接口的类