/*代码高亮*/

java多线程

一,线程创建两种方式

1, 继承java.lang.Thread类

public class Demo1 extends Thread{
@Override
public void run() {
for(int i=01;i<=10;i++){
System.out.println("多线程中循环"+i);
}
}
}

Thread类详解:

1>构造方法
★public Thread():分配一个新的线程对象
★public Thread(Runnable target):分配一个带指定目标的新的线程对象
★public Thread(Runnable target,String name)分配一个带指定目标的新的线程对象,并分配名字
2>常用方法
★public String getName():获取当前线程名称
★public void start():线程开始执行,虚拟机调用线程中的run()方法
★public void run():在此方法中定义线程要执行的任务
★public static void sleep():使当前正在执行的线程以指定毫秒数暂停
★public static Thread currentThread():返回当前正在执行的线程对象的引用
1,实现java.lang.Runnable接口,重写run方法即可
步骤:
★创建runnable实现类的实例,并以此实例创建Thread对象,thread对象才是真正的线程对象
★执行start()

public class Demo2 implements Runnable{
@Override
public void run() {
//获取当前线程
Thread thread=Thread.currentThread();
System.out.println( thread.getName()+"老子要抢资源了");
}
}
public static void main(String[] args) {
//创建runnable实现类的实例,并以此实例创建Thread对象,thread对象才是真正的线程对象
Demo2 demo2=new Demo2();
Thread thread=new Thread(demo2,"二狗子");
//启动线程
thread.start();
}

二,线程安全问题

共享变量增删时会产生线程安全问题
模拟卖票:

public class Ticket implements Runnable {

//共有100张票
private int count=100;
@Override
public void run() {
//获取当前线程对象
Thread thread=Thread.currentThread();
//卖票
while(true){
//有票就卖
if(count>0){
System.out.println(thread.getName()+"出售第"+count--+"张票");
//模拟出票时间
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}
public static void main(String[] args) {
//创建实现类的实例
Ticket ticket=new Ticket();
//三个窗口
Thread thread1=new Thread(ticket,"窗口一");
Thread thread2=new Thread(ticket,"窗口二");
Thread thread3=new Thread(ticket,"窗口三");
thread1.start();
thread2.start();
thread3.start();

}

解决问题:
关键字:synchronized
为保证每个线程都能够正常执行原子操作,java引入线程同步机制
三种方式:
1>同步代码块
synchronized关键字可用在方法中的某个区块中,表示只对次区块实行互斥操作

synchronized(同步锁){
同步操作的代码块
}

同步锁:
@任何时候只允许一个线程拥有同步锁,谁拿到锁就可以执行同步代码块,其他线程在外面等候
@this代表当前正在执行的线程
@可以是任意引用数据类型
改进(this可以换成 thread或者Ticket.class都可以):

public class Ticket implements Runnable {

//共有100张票
private int count=100;
@Override
public void run() {
//获取当前线程对象
Thread thread=Thread.currentThread();
//卖票
while(true){
synchronized (this){
//有票就卖
if(count>0){
System.out.println(thread.getName()+"出售第"+count--+"张票");
//模拟出票时间
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}

}
}
}

2>同步方法

public synchronized void method(){
可能产生安全问题的业务代码
}

3>Lock锁机制
java.util.concurrent.locks.Lock机制提供了比synchronized更广泛的锁定操作,更体现面对对象(因为它把加锁释放锁方法化)
//唯一实现类ReentrantLock(boolean flag)默认false非公平锁,true公平锁
public void lock():加锁
public void unlock():释放同步锁

public class Ticket implements Runnable {

//共有100张票
private int count = 100;
//获取锁对象
private Lock lock = new ReentrantLock();

@Override
public void run() {
//获取当前线程对象
Thread thread = Thread.currentThread();
//卖票
while (true) {
//加锁
lock.lock();
//有票就卖
if (count > 0) {
System.out.println(thread.getName() + "出售第" + count-- + "张票");
//模拟出票时间
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
lock.unlock();
}
}
}

 

posted @ 2020-07-09 09:21  薄皮灌汤包  阅读(121)  评论(1)    收藏  举报