实验十 多线程程序设计
1. 实验目的:
掌握Java多线程程序设计方法;
2. 实验内容:
上机实现下列程序
-
- P386, J_Thread.java;
package shiyan_10;
/**
* 通过构造类thread的子类创建线程的例程
*/
public class J_Thread extends Thread{
private int m_threadId;
public J_Thread(int i){
m_threadId = i;
System.out.println("创建线程"+i);
}
@Override
public void run(){
for (int i = 0; i < 3; i++) {
System.out.println("运行线程"+m_threadId);
try {
Thread.sleep((int)(Math.random()*1000));
}catch (InterruptedException e){
System.err.println("异常InterruptedException:"+e);
e.printStackTrace();
}
}
}
public static void main(String[]
args) {
new J_Thread(1).start();
new J_Thread(2).start();
System.out.println("方法main结束");
}
}
-
- P389, J_ThreadRunnable.java;
package shiyan_10;
public class J_ThreadRunnable implements Runnable{
private int m_threadID;
public J_ThreadRunnable(int i){
m_threadID=i;
System.out.println("创建线程:"+i);
}
public void run(){
for(int i=0;i<3;i++){
System.out.println("运行线程:"+m_threadID);
try{
Thread.sleep((int)(Math.random()*1000));
}
catch(InterruptedException e){
System.err.println("异常 InterruptedException"+e);
e.printStackTrace();
}
}
}
public static void main(String args[]){
Thread t1=new Thread(new J_ThreadRunnable(1));
t1.start();
Thread t2=new Thread(new J_ThreadRunnable(2));
t2.start();
System.out.println("方法main结束");
}
}
-
- P407, J_Experiment.java;
public class J_Experiment {
public static void mb_sleep(long millis) {
try {
Thread.sleep(millis);
}
catch (InterruptedException e) {
System.err.println("异常 InterruptedException:" + e);
e.printStackTrace();
}//try-catch结构结束
}//方法mb_sleep结束
public static synchronized void mb_methodstatic(int id){
System.out.println("线程"+id+"进入静态同步方法");
mb_sleep(1000);
System.out.println("线程"+id+"离开静态同步方法");
}//方法mb_methodStatic结束
public synchronized void mb_methodSynchronized(int id){
System.out.println("线程"+id+"进入非静态同步方法");
mb_sleep(1000);
System.out.println("线程"+id+"离开非静态同步方法");
}//方法methodSynchronized结束
public void mb_method (int id) {
System.out.println("线程" + id + "进入非静态非同步方法");
System.out.println("线程" + id + "高开非静态非同步方法");
mb_sleep(1000):
}//方法mb_method结束
}//类J_Experiment结束
-
- P413, J_BlockClass.java
package shiyan_10;
/**
* 通过基于类对象同步语句块进行线程同步的例程
*/
public class J_BlockClass extends Thread {
public static int m_data = 0;
public static int m_times = 1000;
public int m_id;
public boolean m_done;
J_BlockClass(int id) {
m_id = id;
}
@Override
public void run() {
m_done = false;
int d = ((m_id % 2 == 0) ? 1 : -1);
System.out.println("运行线程:" + m_id + "(增量为:" + d + ")");
try {
synchronized (Class.forName("shiyan_10.J_BlockClass")) {
System.out.println("线程:" + m_id + "进入同步语句块,m_data = " + m_data);
for (int i = 0; i < m_times; i++) {
}
for (int j = 0; j < m_times; j++) {
m_data += d;
}
System.out.println("线程:" + m_id + "离开同步语句块,m_data = " + m_data);
}
} catch (ClassNotFoundException e) {
e.printStackTrace();
System.err.println(e);
}
m_done = true;
System.out.println("结束线程" + m_id);
}
public static void main(String[] args) {
J_BlockClass t1 = new J_BlockClass(1);
J_BlockClass t2 = new J_BlockClass(2);
t1.m_done = false;
t2.m_done = false;
t1.start();
t2.start();
while (!t1.m_done||!t2.m_done){;}
System.out.println("结果:m_data="+m_data);
}
}
-
- P410, J_SynchronizedMethod.java;
package shiyan_10;
/**
*说明在同一个对象中的多个同步方法的运行机制
**/
public class J_SynchronizedMethod extends Thread{
public int m_id;
public J_ExperimentSM m_data;
J_SynchronizedMethod(int id){
m_id = id;
}
@Override
public void run() {
System.out.println("运行线程:"+m_id);
m_data.mb_method1(m_id);
m_data.mb_method2(m_id);
System.out.println("结束线程:"+m_id);
}
public static void main(String[] args) {
int n = 2;
J_SynchronizedMethod[] t = new J_SynchronizedMethod[n];
J_ExperimentSM d = new J_ExperimentSM();
for (int i = 0; i < n; i++) {
t[i] = new J_SynchronizedMethod(i);
t[i].m_data = d;
t[i].start();
}
System.out.println("方法main结束");
}
}
class J_ExperimentSM {
public static void mb_sleep(long millis){
try {
Thread.sleep(millis);
}catch (InterruptedException e){
System.err.println("异常InterruptedException:"+e);
e.printStackTrace();
}
}
public synchronized void mb_method1(int id){
System.out.println("线程"+id+"进入方法1");
mb_sleep(1000);
System.out.println("线程"+id+"离开方法1");
}
public synchronized void mb_method2(int id){
System.out.println("线程"+id+"进入方法2");
mb_sleep(1000);
System.out.println("线程"+id+"离开方法2");
}
}
-
- P418, J_BlockData.java;
package shiyan_10;
/**
* 基于实例对象的同步语句块的实例
*/
public class J_BlockData extends Thread{
public int m_ID;
public J_ExperimentBD m_data;
J_BlockData(int id){
m_ID = id;
}
@Override
public void run() {
System.out.println("运行线程:"+m_ID);
synchronized (m_data){
System.out.println("进入同步语句块的是线程:"+m_ID);
m_data.mb_method1(m_ID);
m_data.mb_method2(m_ID);
System.out.println("离开同步语句块的是线程:"+m_ID);
}
System.out.println("结束线程:"+m_ID);
}
public static void main(String[] args) {
int n = 2;
J_BlockData[] t = new J_BlockData[n];
J_ExperimentBD d = new J_ExperimentBD();
for (int i = 0; i < n; i++) {
t[i] = new J_BlockData(i);
t[i].m_data = d;
t[i].start();
}
System.out.println("main方法结束");
}
}
class J_ExperimentBD extends J_ExperimentSM{
}
-
- P422, J_WaitNotify.java;
package shiyan_10;
/**
* 利用wait和notify成员方法进行线程同步
*/
public class J_WaitNotify {
public static void main(String[] args) {
J_ExperimentWN data = new J_ExperimentWN();
J_AssistantWN threadA = new J_AssistantWN(data);
J_AnalystWN threadB = new J_AnalystWN(data);
threadA.start();
threadB.start();
System.out.println("方法main结束");
} // 方法main结束
}
class J_ExperimentWN {
private int m_temperature, m_pressure;
private boolean m_ready = false;
public synchronized void mb_update(int t, int p) {
System.out.println("进入更新方法内部:");
/* 前面更新的数据还没有被处理 */
if (m_ready) {
System.out.println(" 等待数据分析完成...");
try {
wait(); // 等待数据分析
} catch (Exception e) {
e.printStackTrace();
System.err.println(e);
} // try-catch结构结束
System.out.println(" 继续更新数据...");
} // if语句结束
m_temperature = t;
m_pressure = p;
System.out.println("更新完成: 温度值为" + t + ", 气压值为" + p);
m_ready = true;
notify();
} // 同步方法mb_update结束
public synchronized void mb_analyze() {
System.out.println("进入数据分析方法内部:");
// 数据还没有更新
if (!m_ready) {
System.out.println(" 等待数据更新完成...");
try {
wait(); // 等待数据更新
} catch (Exception e) {
e.printStackTrace();
System.err.println(e);
} // try-catch结构结束
System.out.println(" 继续分析数据...");
} // if语句结束
int t = m_temperature;
int p = m_pressure;
System.out.println("分析完成: 温度值为" + t + ", 气压值为" + p);
m_ready = false;
notify();
} // 同步方法mb_analyze结束
// 类J_Experiment结束
}
class J_AssistantWN extends Thread {
J_ExperimentWN m_data;
public J_AssistantWN(J_ExperimentWN d) {
m_data = d;
} // 构造方法J_Assistant结束
@Override
public void run() {
System.out.println("助理线程开始工作");
int i, j, k;
for (k = 0; k < 3; k++) {
i = (int) (Math.random() * 1000);
j = (int) (Math.random() * 1000);
m_data.mb_update(i, j);
} // for循环结束
System.out.println("助理线程结束工作");
} // 方法run结束
} // 类J_Assistant结束
class J_AnalystWN extends Thread {
J_ExperimentWN m_data;
public J_AnalystWN(J_ExperimentWN d) {
m_data = d;
} // 构造方法J_Analyst结束
@Override
public void run() {
System.out.println("分析员线程开始工作");
for (int k = 0; k < 3; k++) {
m_data.mb_analyze();
}
System.out.println("分析员线程结束工作");
} // 方法run结束
} // 类J_Analyst结束
-
- P426, J_Lock.java;
package shiyan_10;
/**
* 线程死锁例程
*/
public class J_Lock extends Thread {
public static Object m_objectA = new Object();
public static Object m_objectB = new Object();
J_Lock(String s) {
super(s);
}
public static void mb_sleep() {
try {
Thread.sleep((long) Math.random() * 1000);
} catch (InterruptedException e) {
System.err.println("异常InterruptedException:" + e);
e.printStackTrace();
}
}
@Override
public void run() {
boolean t = true;
System.out.println(getName() + "开始运行");
for (; true; t=!t){
synchronized (t?m_objectA:m_objectB){
System.out.println(getName()+":"+(t?"对象A":"对象B")+"被锁住");
mb_sleep();
synchronized (t?m_objectB:m_objectA){
System.out.println(getName()+":"+(t?"对象B":"对象A")+"被锁住");
mb_sleep();
System.out.println(getName()+":"+(t?"对象B":"对象A")+"的锁打开");
}
System.out.println(getName()+":"+(t?"对象A":"对象B")+"的锁打开");
}
}
}
public static void main(String[] args) {
J_Lock l1 = new J_Lock("线程1");
J_Lock l2 = new J_Lock("线程2");
l1.start();
l2.start();
}
}
-
- P429, J_BlaockGranularyity.java。
package shiyan_10;
*/**
* 基于类对象且具有最小同步粒度的线程同步实例
*/* publicclassJ_BlockGranularityextendsThread{
publicstaticint m_data = 0;
publicstaticint m_times = 1000;
publicint m_ID;
publicboolean m_done;
J_BlockGranularity(int id) {
m_ID = id;
}
@Overridepublicvoidrun(){
m_done = false;
int d = ((m_ID % 2) == 0) ? 1 : -1;
System.out.println("运行线程:" + m_ID + "(增量为:" + d + ")");
try {
for (int i = 0; i < m_times; i++) {
}
for (int j = 0; j < m_times; j++) {
synchronized (Class.forName("shiyan_10.J_BlockGranularity")) {
m_data += d;
}
}
} catch (ClassNotFoundException e) {
e.printStackTrace();
System.err.println(e);
}
m_done = true;
System.out.println("结束线程:"+m_ID);
}
publicstaticvoidmain(String[] args){
J_BlockGranularity t1 = new J_BlockGranularity(1);
J_BlockGranularity t2 = new J_BlockGranularity(2);
t1.m_done = false;
t2.m_done = false;
t1.start();
t2.start();
while(!t1.m_done||!t2.m_done){;}
System.out.println("结果:m_data = "+m_data);
}
}
3. 实验要求:
(1) 掌握Java多线程的创建和使用。
(2) 掌握Java多线程同步技术;理解产生死锁现象的原因,学习如何避免死锁。