1. 线程介绍
***多任务是开启线程的出发点
***进程和线程 的区别
进程:资源分配的单位
线程:调度和执行的单位
2. 线程实现
1.线程的创建
----继承Thread类
----实现Runnable接口(推荐)
----实现Callable接口
2.静态代理
—可以用于登录日志
3.lamda
–简化线程的使用,该线程用一次或很
3. 线程状态
1.线程的五种状态:新生、就绪、运行、死亡、阻塞
2.线程的终止:使用标识来终止线程
3.线程的阻塞:sleep可以模拟网络延时等
4.线程分类:
守护线程:是为用户线程服务的;jvm停止不用等待守护线程执行完毕。
用户线程:默认情况下是用户线程,jvm等待用户线程执行完毕
package cn.zwl.threadState;
import javax.swing.text.StyledEditorKit.ForegroundAction;
/**
*
* 线程:守护线程
* @author dell
*
*/
public class DaemonTest {
public static void main(String[] args) {
God god=new God();
You you=new You();
Thread t=new Thread(god);
t.setDaemon(true);//将用户线程调整为守护
t.start();
new Thread(you).start();
}
}
class You extends Thread{
@Override
public void run() {
// TODO Auto-generated method stub
super.run();
for (int i = 0; i < 365; i++) {
System.out.println("happy life");
}
System.out.println("1111111111");
}
}
class God extends Thread{
@Override
public void run() {
// TODO Auto-generated method stub
super.run();
for(;true;) {
System.out.println("God bless you");
}
}
}
|方法|功能 |
|-isAlive()-|-判断线程是否还活着,即线程是否还未终止-|
| -setName()|给线程起一个名字 |
|getName()|获取线程的名字|
|currentThread()|获取当前正在运行的线程对象,也是获取自己本身|
```java
package cn.zwl.threadState;
public class InfoTest {
public static void main(String[] args) {
System.out.println(Thread.currentThread().isAlive());
//设置名字:真实角色+代理角色
MyInfo info=new MyInfo("战斗机");
Thread t=new Thread(info);
t.setName("F35");
t.start();
try {
Thread.sleep(10000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println(Thread.currentThread().isAlive());
}
}
class MyInfo implements Runnable{
private String name;
public MyInfo(String name) {
super();
this.name = name;
}
@Override
public void run() {
// TODO Auto-generated method stub
System.out.println(Thread.currentThread().getName()+"--->"+this.name);
}
}
## 4. 线程同步
同一个对象被多个线程同时来炒作,就会带来不安全
解决办法:队列和锁
两种常用方法:sychronized方法和sychronized块(提高效率)
```java
package cn.zwl.threadsyn;
/*
*
* 同步方法
*/
public class SynTest1 implements Runnable {
//票数
private int ticketNums=100;
boolean flag=true;
@Override
public void run() {
// TODO Auto-generated method stub
while(flag) {
try {
Thread.sleep(200);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
test();
}
}
//线程安全的同步方法,锁住了对象的资源
public synchronized void test() {
if(ticketNums<=0) {
flag=false;
return ;
}
//模拟延时
try {
Thread.sleep(200);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName()+"-->"+ticketNums--);
}
public static void main(String[] args) {
SynTest1 web=new SynTest1();
new Thread(web,"黄牛1").start();
new Thread(web,"黄牛2").start();
new Thread(web,"黄牛3").start();
}
}
package cn.zwl.threadsyn;
/*
*
* 取钱,线程不安全
*/
public class SynTest3 {
public static void main(String[] args) {
Account account=new Account(100, "聘礼");
SafeDrawing3 me=new SafeDrawing3(account, 50, "zwl");
SafeDrawing3 myFriend=new SafeDrawing3(account, 60, "why");
me.start();
myFriend.start();
}
}
class SafeDrawing3 extends Thread{
Account account;//取钱的账户
int drawingMoney;//取得钱数
int packetTotal;//口袋里的钱
public SafeDrawing3(Account account, int drawingMoney,String name) {
super(name);
this.account = account;
this.drawingMoney = drawingMoney;
}
@Override
public void run() {
test();
}
//目标不对锁定失败,应该锁定account
public void test() {
// TODO Auto-generated method stub
synchronized (account) {
if(account.money-drawingMoney<0) {
System.out.println(this.getName()+"对不起,余额不足");
return ;
}
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
account.money-=drawingMoney;
packetTotal+=drawingMoney;
System.out.println(this.getName()+"-->账户余额为:"+account.money);
System.out.println(this.getName()+"-->口袋里的钱为:"+this.packetTotal);
}
}
}
package cn.zwl.threadsyn;
import java.util.ArrayList;
import java.util.List;
/**
*
* 快乐影院
* @author dell
*
*/
class Cinema1{
List<Integer> available;//可用的位置
String name;//名称
public Cinema1(List<Integer> available, String name) {
super();
this.available = available;
this.name = name;
}
//购票
public boolean bookTickets(List<Integer>seats) {
System.out.println("可用位置"+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;
}
}
class Customer1 implements Runnable{
Cinema1 cinema;
List<Integer> seats;
public Customer1(Cinema1 cinema, List<Integer> seats) {
super();
this.cinema = cinema;
this.seats = seats;
}
@Override
public void run() {
// TODO Auto-generated method stub
synchronized (cinema) {
boolean flag=cinema.bookTickets(seats);
if (flag) {
System.out.println("出票成功"+Thread.currentThread().getName()+"->位置为"+seats);
}
else {
System.out.println("出票失败");
}
}
}
}
public class HappyCinema2 {
public static void main(String[] args) {
List<Integer> avaliable=new ArrayList<Integer>();
for(int i=1;i<10;i++) {
avaliable.add(i);
}
List<Integer> seats1=new ArrayList<Integer>();
for(int i=1;i<10;i+=2) {
seats1.add(i);
}
List<Integer> seats2=new ArrayList<Integer>();
for(int i=2;i<10;i+=2) {
seats2.add(i);
}
Cinema1 c=new Cinema1(avaliable,"Happy New Year");
new Thread(new Customer1(c, seats1),"ZWL").start();
new Thread(new Customer1(c, seats2),"WHY").start();
}
}
package cn.zwl.threadsyn;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.CopyOnWriteArrayList;
/*
* import java.util.concurrent.CopyOnWriteArrayList;
* 保证了读写的过程中操作的安全
* 线程安全:操作容器
*/
public class SynContainer {
public static void main(String[] args) throws InterruptedException {
CopyOnWriteArrayList<String> list=new CopyOnWriteArrayList<String>();
for (int i = 0; i < 10; i++) {
new Thread(()->{
//由于用了容器自带的,所以不需要
list.add(Thread.currentThread().getName());
}).start(); ;
}
Thread.sleep(1000);
System.out.println(list.size());//看是否放进去10个数据
}
}