业务:普通的线程代码 Thread
Runnable 没有返回值,效率相比Callable相对较低!
进程:一个程序,QQ.exe,Music.exe 程序的集合
一个进程往往可以有多个线程,至少包含一个
java默认有两个线程,main GC
线程:开了一个进程Typro ,写字,自动保存(线程负责)
java真的可以开启线程吗? 开不了
并发编程:并发,并行
并发(多个线程操作同一个资源)
·cpu一核,模拟出来多线程,快速交替
并行(多个人一起行走)
·cpu多核,多个线程可以同时执行 线程池
package com.xizi.demo01; public class Test { public static void main(String[] args) { //获取cpu的核数 //cpu密集型,IO密集型 System.out.println(Runtime.getRuntime().availableProcessors()); } }
并发编程的本质:充分利用CPU的资源
线程有几个状态
public enum State { /** * Thread state for a thread which has not yet started. */ NEW, //新生 /** * Thread state for a runnable thread. A thread in the runnable * state is executing in the Java virtual machine but it may * be waiting for other resources from the operating system * such as processor. */ RUNNABLE, //运行 /** * Thread state for a thread blocked waiting for a monitor lock. * A thread in the blocked state is waiting for a monitor lock * to enter a synchronized block/method or * reenter a synchronized block/method after calling * {@link Object#wait() Object.wait}. */ BLOCKED, //阻塞 /** * Thread state for a waiting thread. * A thread is in the waiting state due to calling one of the * following methods: *
A thread in the waiting state is waiting for another thread to * perform a particular action. * * For example, a thread that has called Object.wait() * on an object is waiting for another thread to call * Object.notify() or Object.notifyAll() on * that object. A thread that has called Thread.join() * is waiting for a specified thread to terminate. */ WAITING, //等待,死死登台 /** * Thread state for a waiting thread with a specified waiting time. * A thread is in the timed waiting state due to calling one of * the following methods with a specified positive waiting time: *
wait/sleep区别
1.来自不同的类
wait=>Object
sleep=>Thread
2.关于锁的释放
wait会释放锁,sleep睡觉了,不会释放锁
3.是哟个的范围是不同的
wait:必须在同步代码块中
sleep:可以在任何地方睡
4.是否要捕获异常
wait:不需要捕获异常
sleep:必须要捕获异常
传统方式实现Runnable接口 耦合性太差
优化后的传统方式 买票方式
package com.xizi.demo01;
public class SaleTicketTest {
public static void main(String[] args) {
//并发:多个线程操作同一个资源,把资源丢入线程
Ticket ticket = new Ticket();
new Thread(()->{
for (int i = 0; i < 50; i++) {
ticket.sale();
}
},"A").start();
new Thread(()->{
for (int i = 0; i < 50; i++) {
ticket.sale();
}
},"B").start();
new Thread(()->{
for (int i = 0; i < 50; i++) {
ticket.sale();
}
},"C").start();
}
}
//资源类 OOP
class Ticket{
//属性 方法
private int number=30;
//买票的方式
//synchronizedd 本质:队列,锁
public synchronized void sale(){
if (number>0){
System.out.println(Thread.currentThread().getName()+"卖出了第"+(number--)+"张票,剩余"+number+"张");
}
}
}
lock方式
package com.xizi.demo01;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
public class SaleTicketTest2 {
public static void main(String[] args) {
//并发:多个线程操作同一个资源,把资源丢入线程
Ticket2 ticket2 = new Ticket2();
new Thread(()->{ for (int i = 0; i < 50; i++) ticket2.sale(); },"A").start();
new Thread(()->{ for (int i = 0; i < 50; i++) ticket2.sale(); },"B").start();
new Thread(()->{ for (int i = 0; i < 50; i++) ticket2.sale(); },"C").start();
}
}
//Lock 三部曲
//1.new ReentrantLock();
//2.lock.lock(); 加锁
//3.finally=> lock.unlock(); 解锁
class Ticket2 {
//属性 方法
private int number = 30;
Lock lock = new ReentrantLock();
//买票的方式
public void sale() {
lock.lock(); //加锁
try {
//业务代码
if (number > 0) {
System.out.println(Thread.currentThread().getName() + "卖出了第" + (number--) + "张票,剩余" + number + "张");
}
} catch (Exception e) {
e.printStackTrace();
} finally {
lock.unlock(); //解锁
}
}
}
Synchronized和Lock区别
1.Synchronized 内置的Java字 Lock是一个Java类
2.Synchronized 无法判断获取锁的状态,Lock可以判断是否获取到了锁
3.Synchronized 会自动释放锁 Lock必须要手动释放锁! 如果不释放锁,死锁
4.Synchronized 线程1(获取锁,阻塞)线程2(等待, 傻傻的等待);lock锁就不一定会等待下去
5.Synchronized 可重入锁, 不可以中断的 非公平;lock 可重入锁, 非公平(可以自己设置);
6.Synchronized 适合锁少量的代码同步问题 ;lock可以锁大量的代码同步问题;
Synchronized版本
package com.xizi.pc;
public class A {
public static void main(String[] args) {
Data data = new Data();
new Thread(()->{
for (int i = 0; i < 10; i++) {
try {
data.increment();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
},"A").start();
new Thread(()->{
for (int i = 0; i < 10; i++) {
try {
data.decrement();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
},"B").start();
}
}
class Data{
private int number=0;
public synchronized void increment() throws InterruptedException {
if (number!=0){
// 如果不等于0 等待
this.wait();
}
//等于0 +1
number++;
System.out.println(Thread.currentThread().getName()+"=>"+number);
//通知其他线程 我+1完毕了
this.notifyAll();
}
public synchronized void decrement() throws InterruptedException {
if (number==0){
// 如果等于0 等待
this.wait();
}
//不等于0 -1
number--;
System.out.println(Thread.currentThread().getName()+"=>"+number);
//通知其他线程 我+1完毕了
this.notifyAll();
}
}
面试的:单例模式 排序算法 生产者和消费者 死锁
问题存在 A B C D四个线程
package com.xizi.pc; public class A { public static void main(String[] args) { Data data = new Data(); new Thread(()->{ for (int i = 0; i < 10; i++) { try { data.increment(); } catch (InterruptedException e) { e.printStackTrace(); } } },"A").start(); new Thread(()->{ for (int i = 0; i < 10; i++) { try { data.decrement(); } catch (InterruptedException e) { e.printStackTrace(); } } },"B").start(); new Thread(()->{ for (int i = 0; i < 10; i++) { try { data.increment(); } catch (InterruptedException e) { e.printStackTrace(); } } },"C").start(); new Thread(()->{ for (int i = 0; i < 10; i++) { try { data.decrement(); } catch (InterruptedException e) { e.printStackTrace(); } } },"D").start(); } } class Data{ private int number=0; public synchronized void increment() throws InterruptedException { while (number!=0){ // 如果不等于0 等待 this.wait(); } //等于0 +1 number++; System.out.println(Thread.currentThread().getName()+"=>"+number); //通知其他线程 我+1完毕了 this.notifyAll(); } public synchronized void decrement() throws InterruptedException { while (number==0){ // 如果等于0 等待 this.wait(); } //不等于0 -1 number--; System.out.println(Thread.currentThread().getName()+"=>"+number); //通知其他线程 我+1完毕了 this.notifyAll(); } }