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(); } } }

浙公网安备 33010602011771号