用synchronized关键字及concurrent.locks解决线程并发问题

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.实战中的经验

ServiceData sdataT = new ServiceData();
sdataT.addInputData("pk_ids", pk_ids);

System.out.println("--------1");
//import jos.framework.appsrv.JosRunnable;
JosRunnable jrun = new JosRunnable(sdataT) {

ServiceData sdataT = (jos.engine.core.ServiceData) this.getServiceData();
String pk_ids = sdataT.getInputAsString("pk_ids");

@Override
protected void end() {
System.out.println("--------6---end()方法执行了");
//1-处理成功
/****** 更新区县核对批次汇总信息 打包状态******/
String UPDATE_HDPC_SQL = "UPDATE dsr_hc_pc SET clzt = ?, pstr1 = ? WHERE pch = ?;";
jdbcTemplate.executeUpdate(UPDATE_HDPC_SQL, new Object[]{ 1, "打包成功", hdpch });
}

@Override
public void run() {
synchronized (this) {
try {
//2-处理中
/****** 更新区县核对批次汇总信息 打包状态******/
String UPDATE_HDPC_SQL = "UPDATE dsr_hc_pc SET clzt = ?, pstr1 = ? WHERE pch = ?;";
jdbcTemplate.executeUpdate(UPDATE_HDPC_SQL, new Object[]{ 2, "打包中", hdpch }); //打包是要将数据推到dsr_hc_jz,dsr_hc_person
System.out.println("--------2");
String[] spkid = pk_ids.split(",");
hdzhs = spkid.length;//核对总户数
System.out.println("--------3");
for(int i = 0; i < spkid.length; i++) {
String QUERY_SQL2 = "SELECT a.pk_sr_main AS pk_id, a.mdjlx, a.sys_xzqh, a.mjtrk FROM sr_main a, mz_xzjg b WHERE a.sys_xzqh = b.xzqh_id AND a.pk_sr_main = ?";
RowList rowList = AspDaoUtil.getJdbcTemplate().queryRowList(QUERY_SQL2, new Object[]{ spkid[i] });
FieldList field = rowList.get(0);
System.out.println("--------4");
//将数据推到核对
shjzToHd(msyhd,hdpch, field.get("pk_id"), field.get("mdjlx"), field.get("sys_xzqh"), xzqh, sys_zdr, sys_zdrid, deptId, shjzToDsrManager,rhdc);
//核对批次监管,数据到待发送
String UPDATE_HDPCQR_SQL = "UPDATE dsr_hc_pc SET qrzt = ? WHERE pch = ?";
jdbcTemplate.executeUpdate(UPDATE_HDPCQR_SQL, new Object[]{ 1, hdpch });
}

end();
} catch (Exception e) {
e.printStackTrace();
System.out.println("--------9");
//9-处理失败
/****** 更新区县核对批次汇总信息 打包状态******/
String UPDATE_HDPC_SQL = "UPDATE dsr_hc_pc SET clzt = ? WHERE pch = ?;";
jdbcTemplate.executeUpdate(UPDATE_HDPC_SQL, new Object[]{ 9,hdpch });
}
}


}

};

jrun.startNow();

原文地址:https://www.cnblogs.com/tongcc/p/13972781.html