第一种多线程锁
/**
* 代码块锁
* @author Administrator
*
*/
package com.nm;
public class sellTicket implements Runnable {
//定义在run方法外保证对象不会被重复创建,多个线程共同享用该对象
// 总票数
private int ticket = 100;
// 锁对象
Object o = new Object();
@Override
public void run() {// 方法体(多线程情况下cpu会让线程1运行一段时间后让线程1休息再让其他线程运行一段时间)
// 使用while(true)的作用:
// run方法中的代码就是线程要运行的代码,运行完毕以后,就不会再次运行,其方法本身并不是无限循环的。
// 而while(true)是为了让run方法中的代码不断重复的运行,也就是让线程不停的运行,便于查看效果。
// 如果去掉,run运行结束,线程也就结束了。
// 当然,while(true)并不是run()方法必须的,如果线程的run()部分只需要执行一次,则不需要嵌套while(true)循环。
// 比如线程1运行结束,其他线程就不会再运行了,之前遇到我一直在疑惑为什么是单线程
while (true) {
// 1.同步代码块(加在代码块上)
synchronized (o) {
if (ticket > 0) {
System.out.println(Thread.currentThread().getName() + "ticket:" + ticket--);
}
}
}
}
}
测试多线程
package com.nm;
public class TsetThread {
public static void main(String[] args) {
sellTicket sell=new sellTicket();
Thread t1=new Thread(sell);
t1.setName("线程1:");
t1.setPriority(1);
Thread t2=new Thread(sell);
t2.setName("线程2:");
t2.setPriority(1);
Thread t3=new Thread(sell);
t3.setName("线程3:");
t3.setPriority(1);
t1.start();
t2.start();
t3.start();
}
}
第二种锁
package com.nm;
/**
* 方法锁
* @author Administrator
*
*/
public class sellTicket2 implements Runnable {
//定义在run方法外保证对象不会被重复创建,多个线程共同享用该对象
private int ticket = 100;
@Override
public void run() {
while (true) {
sellticket();
}
}
//同步方法:只允许一个线程进入
public synchronized void sellticket() {
if (ticket > 0) {
System.out.println(Thread.currentThread().getName() + "ticket:" + ticket);
ticket--;
}
}
}
测试同理(略)
第三种 lock接口实现锁(新)
package com.nm;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
/**
* lock()获取锁 unlock()释放锁
*
* @author Administrator
*
*/
public class sellTicket3 implements Runnable {
//定义在run方法外保证对象不会被重复创建,多个线程共同享用该对象
private int ticket = 100;
Lock lock = new ReentrantLock();
@Override
public void run() {
while (true) {
//方法前加锁
lock.lock();
try {
if (ticket > 0) {
System.out.println(Thread.currentThread().getName() + "ticket:" + ticket);
ticket--;
}
}catch (Exception e) {
// TODO: handle exception
}finally {
//方法后解除锁
lock.unlock();
}
}
}
}
使用线程池启动多线程 (线程的容器可放在集合)
run方法
package com.nm.pool;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
/**
* lock
* @author Administrator
*
*/
public class sellTicket4 implements Runnable {
//定义在run方法外保证对象不会被重复创建,多个线程共同享用该对象
private int ticket = 100;
Lock lock = new ReentrantLock();
@Override
public void run() {
while (true) {
lock.lock();
try {
if (ticket > 0) {
System.out.println(Thread.currentThread().getName() + "ticket:" + ticket);
ticket--;
}
}catch (Exception e) {
// TODO: handle exception
}finally {
lock.unlock();
}
}
}
}
测试线程池
package com.nm.pool;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
/**
* 使用线程池
* 线程执行完不会销毁会返回线程池
* @author Administrator
*
*/
public class TestPool {
public static void main(String[] args) {
//调用线程池的工厂类Executors的静态方法创建线程池数
ExecutorService es=Executors.newFixedThreadPool(3);
//启动线程
es.submit(new sellTicket4());
es.submit(new sellTicket4());
es.submit(new sellTicket4());
// es.shutdown();销毁线程不建议使用
}
}