掌握多线程几乎是现在互联网企业的必需要求,多线程在处理高并发时有不可替代的作用,工作中常常会使用多线程,却往往是拿来就用的方式,在学校时记得知识点已经有些模糊,面试时强行记忆的理论也忘的差不多了,所以在上班空闲时间整理概括了一下多线程的基础知识点,时不时拿出来巩固下基础理论,写代码时总会有种豁然开朗的感觉,由此希望这篇内容同样可以帮助到你。
创建线程的方式:
- 继承thread类
- 实现runnable接口(可传参)
- 实现callable接口和FutureTask(有返回值)
线程命名:setname 和getname 或创建线程对象时命名new Thread(“张三”)
线程休眠.sleep(休眠时间ms)
设置线程优先级: .setPriority(int 级别) 优先级为1-10,默认为5 ps:java中对于不同优先级的线程调度是抢占式的,所以线程优先级高低只是代表线程抢占到cpu的几率高低,并不是优先级越高线程就先执行完。
获得当前运行线程:Thread.currentThread()
代码:第一种创建线程的方式
Public class myThread extends Thread{
@Override
public void run() {
for(int i=0;i<100;i++){
System.out.println(getName()+"执行到了第"+i+"次");
}
}
Public static void main (String[] agrs){
//创建线程对象
Thread t1 = new MyThread();
//启用线程
t1.start();
}
第二种创建线程的方式
Public class MyRunnable implements Runnable{
@Override
public void run() {
for (int i = 0; i < 100; i++) {
System.out.println(Thread.currentThread().getName()+"执行了"+i);
}
}
}
Public static void main(String[] args){
Runnable r1 = new MyRunnable();
Thread t1 = new Thread(r1);
t1.sleep(100);//休眠100ms后
t1.start();
}
第三种创建线程的方式
Public class Mycallcable implements Callable<String> {
@Override
public String call() throws Exception {
for (int i = 0; i < 100; i++) {
System.out.println(Thread.currentThread().getName()+"连接了
"+i+"次");
}
return "成功!";
}
}
~Main{
Callable<String> c1 = new Mycallable();
FutureTask<String> f1 = new FutureTask(c1);
Thread t1 = new Thread(f1);
Callable<String> c2 = new Mycallable();
FutureTask<String> f2 = new FutureTask(c2);
Thread t2 = new Thread(f2);
//设置线程优先级
t1.setPriority(1);
t2.setPriority(10);
t1.start();
t2.start();
//打印返回值
String ff = f1.get();
System.out.println(ff);
}
线程的生命周期
新建——就绪——运行——阻塞——死亡
流程图:
线程的同步问题
- 同步方法或者同步代码块 使用synchronized实现同步
- 手动加锁lock
同步代码块
Synchronized(){
}
同步方法
以Synchronized修饰的方法,里面是要执行的代码块。
手动方式:
创建Lock接口实现类的对象实例
在代码块之前加锁lock.lock();
执行后解锁lock.unlock();
实例代码如下:
public class Mythread extends Thread {
private static Lock lock = new ReentrantLock();
private static int count = 50;
private static int ticket = 1;
private static Object obj = new Object();
@Override
public void run() {
while (true) {
lock.lock();
try {
Thread.sleep(20);
if (count <= 0) {
System.out.println("已售罄");
break;
}
System.out.println(Thread.currentThread().getName() + "已售出第" + ticket++ + "张票");
count--;
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
lock.unlock();
}
}
}
}
死锁:
两个或两个以上的线程相互拥有对方的资源而不释放产生死锁
生产者和消费者模式:
厨师和顾客的例子。
生产者(厨师):
- 桌子上是否有食物
- 如果没有,烹饪食物,如果有,等待。
- 烹饪完毕后叫顾客吃
消费者(顾客):
- 桌子上是否有食物
- 如果有,吃掉,然后叫厨师烹饪,如果没有,等待。
代码:
生产者代码:
public class Cooker extends Thread {
private Desk desk;
public Cooker(Desk desk) {
this.desk = desk;
}
@Override
public void run() {
while (true) {
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
synchronized (desk.getObj()) {
if(desk.getFoodCount()==0){
break;
}else {
if (desk.isFoodDesk()) {
try {
desk.getObj().wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
} else {
System.out.println(Thread.currentThread().getName()+"生产者生产了食物");
// desk.setFoodCount(desk.getFoodCount()+1);
desk.setFoodDesk(true);
desk.getObj().notifyAll();
}
}
}
}
}
}
消费者代码:
public class Consume extends Thread {
private Desk desk;
public Consume(Desk desk) {
this.desk = desk;
}
@Override
public void run() {
while (true) {
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
synchronized (desk.getObj()) {
if (desk.getFoodCount() == 0) {
break;
} else {
if (desk.isFoodDesk()) {
System.out.println("消费者吃掉了食物");
desk.setFoodDesk(false);
desk.getObj().notifyAll();
desk.setFoodCount(desk.getFoodCount() - 1);
try {
desk.getObj().wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}
}
}
调用生产者消费者模式类:
public class test {
public static void main(String[] args) {
Desk desk = new Desk();
Cooker c = new Cooker(desk);
Consume cs = new Consume(desk);
Cooker c1 = new Cooker(desk);
c.setName("厨师A");
c1.setName("厨师B");
c1.start();
c.start();
cs.start();
}
}
参数bean 类
public class Desk {
private boolean foodDesk;
private int foodCount;
private final Object obj = new Object();
public Desk() {
this(true,10);
}
public Desk(boolean foodDesk,int foodCount) {
this.foodDesk=foodDesk;
this.foodCount = foodCount;
}
public boolean isFoodDesk() {
return foodDesk;
}
public void setFoodDesk(boolean foodDesk) {
this.foodDesk = foodDesk;
}
public int getFoodCount() {
return foodCount;
}
public void setFoodCount(int foodCount) {
this.foodCount = foodCount;
}
public Object getObj() {
return obj;
}
}