1.测试:未作并发处理
package tcc.test.threadSafeTest;
/**
* @author tcc:
* @version 创建时间:2020年
* 类说明:线程安装测试以:没用synchronized关键字时;
*/
public class ThreadUnSecurity {
static int tickets = 10;
class SellTickets implements Runnable{
@Override
public void run() {
// 未加同步时产生脏数据
while(tickets > 0) {
System.out.println(Thread.currentThread().getName()+"--->售出第: "+tickets+" 票");
tickets--;
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
if (tickets <= 0) {
System.out.println(Thread.currentThread().getName()+"--->售票结束!");
}
}
}
public static void main(String[] args) {
SellTickets sell = new ThreadUnSecurity().new SellTickets();
Thread thread1 = new Thread(sell, "1号窗口");
Thread thread2 = new Thread(sell, "2号窗口");
Thread thread3 = new Thread(sell, "3号窗口");
Thread thread4 = new Thread(sell, "4号窗口");
thread1.start();
thread2.start();
thread3.start();
thread4.start();
}
}
结果:
1号窗口--->售出第: 10 票
3号窗口--->售出第: 10 票
2号窗口--->售出第: 10 票
4号窗口--->售出第: 10 票
1号窗口--->售出第: 6 票
3号窗口--->售出第: 5 票
2号窗口--->售出第: 5 票
4号窗口--->售出第: 5 票
1号窗口--->售出第: 2 票
4号窗口--->售出第: 1 票
2号窗口--->售出第: 1 票
3号窗口--->售出第: 1 票
1号窗口--->售票结束!
3号窗口--->售票结束!
4号窗口--->售票结束!
2号窗口--->售票结束!
2.测试:用synchronized同步代码块;或者在方法前加synchronized关键字,写个同步方法
package tcc.test.threadSafeTest;
/**
* @author tcc:
* @version 创建时间:2020年
* 类说明:
*/
public class ThreadSynchronizedSecurity {
static int tickets = 10;
class SellTickets implements Runnable{
@Override
public void run() {
// 同步代码块
while(tickets > 0) {
//其实就是将crud的业务逻辑写在synchronized的保护的作用域中
synchronized (this) {
// System.out.println(this.getClass().getName().toString());
if (tickets <= 0) {
return;
}
System.out.println(Thread.currentThread().getName()+"--->售出第: "+tickets+" 票");
tickets--;
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
if (tickets <= 0) {
System.out.println(Thread.currentThread().getName()+"--->售票结束!");
}
}
}
}
public static void main(String[] args) {
SellTickets sell = new ThreadSynchronizedSecurity().new SellTickets();
Thread thread1 = new Thread(sell, "1号窗口");
Thread thread2 = new Thread(sell, "2号窗口");
Thread thread3 = new Thread(sell, "3号窗口");
Thread thread4 = new Thread(sell, "4号窗口");
thread1.start();
thread2.start();
thread3.start();
thread4.start();
}
}
输出:
1号窗口--->售出第: 10 票
1号窗口--->售出第: 9 票
1号窗口--->售出第: 8 票
1号窗口--->售出第: 7 票
1号窗口--->售出第: 6 票
1号窗口--->售出第: 5 票
1号窗口--->售出第: 4 票
1号窗口--->售出第: 3 票
1号窗口--->售出第: 2 票
1号窗口--->售出第: 1 票
1号窗口--->售票结束!
3.concurrent.locks加锁及释放锁
package tcc.test.threadSafeTest;
/**
* @author tcc:
* @version 创建时间:2020年
* 类说明:lock方法
*/
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
public class ThreadLockSecurity {
static int tickets = 10;
class SellTickets implements Runnable{
Lock lock = new ReentrantLock();
@Override
public void run() {
// Lock锁机制
while(tickets > 0) {
try {
lock.lock();//加锁
if (tickets <= 0) {
return;
}
System.out.println(Thread.currentThread().getName()+"--->售出第: "+tickets+" 票");
tickets--;
} catch (Exception e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}finally {
lock.unlock();//解锁
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
if (tickets <= 0) {
System.out.println(Thread.currentThread().getName()+"--->售票结束!");
}
}
}
public static void main(String[] args) {
SellTickets sell = new ThreadLockSecurity().new SellTickets();
Thread thread1 = new Thread(sell, "1号窗口");
Thread thread2 = new Thread(sell, "2号窗口");
Thread thread3 = new Thread(sell, "3号窗口");
Thread thread4 = new Thread(sell, "4号窗口");
thread1.start();
thread2.start();
thread3.start();
thread4.start();
}
}
1号窗口--->售出第: 10 票
2号窗口--->售出第: 9 票
4号窗口--->售出第: 8 票
3号窗口--->售出第: 7 票
1号窗口--->售出第: 6 票
2号窗口--->售出第: 5 票
4号窗口--->售出第: 4 票
3号窗口--->售出第: 3 票
1号窗口--->售出第: 2 票
2号窗口--->售出第: 1 票
3号窗口--->售票结束!
1号窗口--->售票结束!
2号窗口--->售票结束!
4.实战中的经验