文章目录
多线程介绍
进程 | 线程 | |
---|---|---|
根本区别 | 作为资源分配的单位 | 调度和执行的单位 |
开销 | 每个进程都有独立的代码和数据空间(进程上下文),进程间的切换会有较大的开销 | 线程可以看成是轻量级的进程,同一类线程共享代码和数据空间,每个线程有独立的运行和程序计数器,线程切换开销小 |
环境 | 系统在运行的时候会为每个进程分配不同的内存区域 | 除了cpu之外,不会为线程分配内存,线程所使用的资源是它所属的进程的资源,线程只能共享资源 |
包含关系 | 没有线程的进程可以被看作单线程的,如果一个进程内拥有多个线程,则执行过程不是一条线的,而是多条线共同完成的 | 线程是进程的一部分,所以线程有的时候被称为轻量级进程 |
创建线程
继承Thread
public class extendsThread extends Thread{
@Override
public void run() {
for(int i=0;i<5;i++)
{
System.out.println("Thread..."+i);
}
}
public static void main(String[] args) {
extendsThread thread = new extendsThread();
thread.start();
for(int i=0;i<5;i++)
{
System.out.println("main..."+i);
}
}
}
实现Runnable接口
类实现Runnable接口+重写run()方法
public class RunnableTest implements Runnable{
@Override
public void run() {
for(int i=0;i<5;i++)
{
System.out.println("Thread..."+i);
}
}
public static void main(String[] args) {
RunnableTest runnable = new RunnableTest();
new Thread(runnable).start();
for(int i=0;i<5;i++)
{
System.out.println("main..."+i);
}
}
}
##实现Callable接口
可返回值,可对外声明异常
public class CallableTest implements Callable{
@Override
public Object call() throws Exception {
return null;
}
public static void main(String[] args) throws InterruptedException, ExecutionException {
//创建线程
ExecutorService ser = Executors.newFixedThreadPool(1);
//提交执行
Future result = ser.submit(new CallableTest());
//获取结果
boolean r = (boolean) result.get();
//关闭服务
ser.shutdown();
}
}
lambda
public class ThreadTest {
//静态内部类
static class Test implements Runnable{
public void run()
{
System.out.println("*");
}
}
public static void main(String[] args) {
new Thread(new Test()).start();
//局部内部类
class Test2 implements Runnable{
public void run()
{
System.out.println("**");
}
}
new Thread(new Test2()).start();
//匿名内部类
new Thread(new Runnable(){
public void run()
{
System.out.println("***");
}
}).start();
//简化线程 lambda
new Thread(()->{
System.out.println("****");
}
) .start();
}
}
线程状态
State state = null;
Thread thread= new Thread(()->{
for(int i=0;i<3;i++)
{
try {
Thread.sleep(1000); //TIMED_WAITING
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
state=thread.getState();
System.out.println(state);//NEW
thread.start(); //RUNNABLE
state = thread.getState();
System.out.println(state);
while(state!=Thread.State.TERMINATED)
{
state = thread.getState();
System.out.println(state);
}
//TERMINATED
state = thread.getState();
System.out.println(state);
优先级
1-10
只是概率高低,不代表先后顺序
NORM-PRIORITY:5 默认值
MIN-PRIORITY:1
MAX-PRIORITY:10
守护线程
Thread.setDaemon(true)
为用户线程服务,jvm停止不用等待守护线程执行完毕
同步项目
快乐影院
class Cinema{
private List<Integer> seats;
String name;
public Cinema(List<Integer> seats,String name)
{
this.seats = seats;
this.name=name;
}
//购票
public boolean book(List<Integer> need)
{
System.out.println("可用位置:"+seats);
List<Integer> copyList = new ArrayList<Integer>();
//拷贝
copyList.addAll(seats);
//差
copyList.removeAll(need);
//System.out.println(seats+" "+copyList);
int seatNum = seats.size()-copyList.size();
if(seatNum!=need.size())
{
return false;
}
seats=copyList;
return true;
}
public String getName() {
return name;
}
public List<Integer> getSeats() {
return seats;
}
}
class Customer implements Runnable{
private Cinema cinema;
List<Integer> need;
public Customer(Cinema cinema,List<Integer> need)
{
this.cinema=cinema;
this.need=need;
}
public void run()
{
synchronized(cinema)
{
boolean flag = cinema.book(need);
if(flag)
{
System.out.println("购"+cinema.getName()+"票成功,购票人"
+Thread.currentThread().getName()+",位置为"+need
+" 剩余位置 "+cinema.getSeats());
}else {
System.out.println("购"+cinema.getName()+"票失败,购票人"+Thread.currentThread().getName()+",位置不够");
}
}
}
}
List<Integer> seats = new ArrayList<Integer>();
seats.add(1);
seats.add(3);
seats.add(6);
seats.add(4);
Cinema cinema = new Cinema(seats,"Happy Cinema");
List<Integer> need = new ArrayList<Integer>();
need.add(1);
need.add(3);
Customer c1 = new Customer(cinema,need);
new Thread(c1,"A").start();
List<Integer> need2 = new ArrayList<Integer>();
need2.add(6);
//need2.add(4);
Customer c2 = new Customer(cinema,need2);
new Thread(c2,"B").start();
法二:
class Passanger extends Thread{
private int seats;
public Passanger(Runnable target,String name,int seats)
{
super(target,name);
this.seats=seats;
}
public int getSeats() {
return seats;
}
}
class web implements Runnable{
private int ticket;
private String name;
public web(int ticket,String name)
{
this.ticket=ticket;
this.name=name;
}
private boolean book(int need)
{
System.out.println("可用票 "+ticket);
if(need>ticket)
{
return false;
}
ticket-=need;
return true;
}
public void run()
{
synchronized(this) {
Passanger p=(Passanger) Thread.currentThread();
boolean flag = book(p.getSeats());
if(flag)
{
System.out.println(Thread.currentThread().getName()+ " 购"+name+"票成功 ");
}
else {
System.out.println(Thread.currentThread().getName()+" 购"+name+"票失败");
}
}
}
}
web w = new web(3,"火车票网");
new Passanger(w,"A",2).start();
new Passanger(w,"B",2).start();
CopyOnWriteArrayList
并发容器
死锁
过多的同步可能造成对象的死锁
相互持有对方的对象锁
| synchronized(A)
{
synchronized(B)
{
}
} | synchronized(B)
{
synchronized(A)
{
}
} |
---|
管程法
//生产者
class Productor extends Thread{
Container container;
public Productor(Container container) {
this.container = container;
}
public void run()
{
for(int i=1;i<=100;i++)
{
System.out.println("生产第 "+i+" 个馒头");
container.push(new Steam(i));
}
}
}
//消费者
class Customers extends Thread{
Container container;
public Customers(Container container) {
this.container = container;
}
public void run()
{
for(int i=1;i<=100;i++)
{
System.out.println("消费第 "+container.pop().id+" 个馒头");
}
}
}
//缓冲区
class Container{
Steam[] steam = new Steam[10];
int count=0;
public synchronized void push(Steam s)
{
if(count==steam.length)
{
try {
this.wait();//线程阻塞 消费者通知生产解除
} catch (InterruptedException e) {
e.printStackTrace();
}
}
//生产
steam[count]=s;
count++;
this.notifyAll();//通知消费
}
public synchronized Steam pop()
{
if(count==0)
{
try {
this.wait(); //线程阻塞 生产者通知消费解除
} catch (InterruptedException e) {
e.printStackTrace();
}
}
//消费
count--;
Steam sm=steam[count];
this.notifyAll();//通知生产
return sm;
}
}
//馒头
class Steam{
int id;
public Steam(int id) {
this.id = id;
}
}
Container c = new Container();
new Productor(c).start();
new Customers(c).start();
信号灯法
class Productors2 extends Thread{
TV tv;
public Productors2(TV tv) {
this.tv = tv;
}
public void run() {
for(int i=0;i<10;i++)
{
if(i%2==0)
{
tv.play("综艺");
}else {
tv.play("电影");
}
}
}
}
class Customers2 extends Thread{
TV tv;
public Customers2(TV tv) {
this.tv = tv;
}
public void run() {
for(int i=0;i<10;i++)
{
tv.watch();
}
}
}
class TV{
String voice;
//信号灯
//T-演员表演 观众等待
//F-观众观看 演员等待
boolean flag = true;
public synchronized void play(String voice) {
if(!flag)
{
try {
this.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println("表演了:"+voice);
this.voice=voice;
this.notifyAll();
this.flag=!flag;
}
public synchronized void watch()
{
if(flag)
{
try {
this.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println("听到了:"+voice);
this.notifyAll();
this.flag=!flag;
}
}
TV tv=new TV();
new Productors2(tv).start();
new Customers2(tv).start();
定时调度
Timer timer = new Timer();
timer.schedule(TimeTask,time);//time后执行指定任务
timer.schedule(TimeTask,time,period);//重复的执行时间
quartz
volitale
可重入锁
锁可传递,计数 ReentrantLock