线程同步

多线程并发运行不确定性问题解决方案:引入线 程同步机制,使得另一线程要使用该方法,就只 能等待。

⚫ 在Java中解决多线程同步问题的方法有两种:

1.- Java SE 5.0中引入ReentrantLock类(P648页)。

2.- 在共享内存的类方法前加synchronized修饰符。

……

public synchronized static void sub(int m)

……

解决方案一:锁对象与条件对象

用ReentrantLock保护代码块的基本结构如下:

myLock.lock();

try {

   critical section

} finally{

myLock.unlock(); }

有关锁对象和条件对象的关键要点:

➢ 锁用来保护代码片段,保证任何时刻只能有一 个线程执行被保护的代码。

➢ 锁管理试图进入被保护代码段的线程。

➢ 锁可拥有一个或多个相关条件对象。

➢ 每个条件对象管理那些已经进入被保护的代码 段但还不能运行的线程。

解决方案二: synchronized关键字

synchronized关键字作用:

➢ 某个类内方法用synchronized 修饰后,该方法被称为同步方法;

➢ 只要某个线程正在访问同步方法,其他线程欲要访问同步方法就被阻塞,直至线程从同步方法返回前唤醒被阻塞线程,其他线程方可能进入同步方法。

➢ 一个线程在使用的同步方法中时,可能根据问题的需要,必须使用wait()方法使本线程等待,暂时让出CPU的使用权,并允许其它线程使用这个同步方法。

➢ 线程如果用完同步方法,应当执行notifyAll()方 法通知所有由于使用这个同步方法而处于等待的 线程结束等待。

第二部分:实验部分——线程同步控制

实验时间 2018-12-10

1、实验目的与要求

(1) 掌握线程同步的概念及实现技术;

(2) 线程综合编程练习

2、实验内容和步骤

实验1:测试程序并进行代码注释。

测试程序1:

1.在Elipse环境下调试教材651页程序14-7,结合程序运行结果理解程序;

2.掌握利用锁对象和条件对象实现的多线程同步技术。

package synch;

import java.util.*;
import java.util.concurrent.locks.*;

/**
一个银行有许多银行帐户,使用锁序列化访问 * @version 1.30 2004-08-01
* @author Cay Horstmann
*/
public class Bank
{
private final double[] accounts;
private Lock bankLock;
private Condition sufficientFunds;

/**
* 建设银行。
* @param n 账号
* @param initialBalance 每个账户的初始余额
*/
public Bank(int n, double initialBalance)
{
accounts = new double[n];
Arrays.fill(accounts, initialBalance);
bankLock = new ReentrantLock();
sufficientFunds = bankLock.newCondition();
}

/**
* 把钱从一个账户转到另一个账户。
* @param 从账户转账
* @param 转到要转账的账户
* @param 请允许我向你转达
*/
public void transfer(int from, int to, double amount) throws InterruptedException
{
bankLock.lock();
try
{
while (accounts[from] < amount)
sufficientFunds.await();
System.out.print(Thread.currentThread());
accounts[from] -= amount;
System.out.printf(" %10.2f from %d to %d", amount, from, to);
accounts[to] += amount;
System.out.printf(" Total Balance: %10.2f%n", getTotalBalance());
sufficientFunds.signalAll();
}
finally
{
bankLock.unlock();
}
}

/**
* 获取所有帐户余额的总和。
* @return 总余额
*/
public double getTotalBalance()
{
bankLock.lock();
try
{
double sum = 0;

for (double a : accounts)
sum += a;

return sum;
}
finally
{
bankLock.unlock();
}
}

/**
* 获取银行中的帐户数量。
* @return 账号
*/
public int size()
{
return accounts.length;
}
}

package synch;

/**
* 这个程序显示了多个线程如何安全地访问数据结构。
* @version 1.31 2015-06-21
* @author Cay Horstmann
*/
public class SynchBankTest
{
public static final int NACCOUNTS = 100;
public static final double INITIAL_BALANCE = 1000;
public static final double MAX_AMOUNT = 1000;
public static final int DELAY = 10;

public static void main(String[] args)
{
Bank bank = new Bank(NACCOUNTS, INITIAL_BALANCE);
for (int i = 0; i < NACCOUNTS; i++)
{
int fromAccount = i;
Runnable r = () -> {
try
{
while (true)
{
int toAccount = (int) (bank.size() * Math.random());
double amount = MAX_AMOUNT * Math.random();
bank.transfer(fromAccount, toAccount, amount);
Thread.sleep((int) (DELAY * Math.random()));
}
}
catch (InterruptedException e)
{
}
};
Thread t = new Thread(r);
t.start();
}
}
}

测试程序2:

l 在Elipse环境下调试教材655页程序14-8,结合程序运行结果理解程序;

l 掌握synchronized在多线程同步中的应用。

实验代码:

package synch2;

import java.util.*;

/**
* A bank with a number of bank accounts that uses synchronization primitives.
* @version 1.30 2004-08-01
* @author Cay Horstmann
*/
public class Bank
{
private final double[] accounts;

/**
* Constructs the bank.
* @param n the number of accounts
* @param initialBalance the initial balance for each account
*/
public Bank(int n, double initialBalance)
{
accounts = new double[n];
Arrays.fill(accounts, initialBalance);
}

/**
* Transfers money from one account to another.
* @param from the account to transfer from
* @param to the account to transfer to
* @param amount the amount to transfer
*/
public synchronized void transfer(int from, int to, double amount) throws InterruptedException
{
while (accounts[from] < amount)
wait();
System.out.print(Thread.currentThread());
accounts[from] -= amount;
System.out.printf(" %10.2f from %d to %d", amount, from, to);
accounts[to] += amount;
System.out.printf(" Total Balance: %10.2f%n", getTotalBalance());
notifyAll();
}

/**
* Gets the sum of all account balances.
* @return the total balance
*/
public synchronized double getTotalBalance()
{
double sum = 0;

for (double a : accounts)
sum += a;

return sum;
}

/**
* Gets the number of accounts in the bank.
* @return the number of accounts
*/
public int size()
{
return accounts.length;
}
}

package synch2;

/**
* This program shows how multiple threads can safely access a data structure,
* using synchronized methods.
* @version 1.31 2015-06-21
* @author Cay Horstmann
*/
public class SynchBankTest2
{
public static final int NACCOUNTS = 100;
public static final double INITIAL_BALANCE = 1000;
public static final double MAX_AMOUNT = 1000;
public static final int DELAY = 10; public static void main(String[] args)
{
Bank bank = new Bank(NACCOUNTS, INITIAL_BALANCE);
for (int i = 0; i < NACCOUNTS; i++)
{
int fromAccount = i;
Runnable r = () -> {
try
{
while (true)
{
int toAccount = (int) (bank.size() * Math.random());
double amount = MAX_AMOUNT * Math.random();
bank.transfer(fromAccount, toAccount, amount);
Thread.sleep((int) (DELAY * Math.random()));
}
}
catch (InterruptedException e)
{
}
};
Thread t = new Thread(r);
t.start();
}
}
}

测试程序3:

l 在Elipse环境下运行以下程序,结合程序运行结果分析程序存在问题;

l 尝试解决程序中存在问题。

class Cbank

{

private static int s=2000;

public   static void sub(int m)

{

int temp=s;

temp=temp-m;

try {

Thread.sleep((int)(1000*Math.random()));

}

catch (InterruptedException e)  {              }

s=temp;

System.out.println("s="+s);

}

}

class Customer extends Thread

{

public void run()

{

for( int i=1; i<=4; i++)

Cbank.sub(100);

}

}

public class Thread3

{

public static void main(String args[])

{

Customer customer1 = new Customer();

Customer customer2 = new Customer();

customer1.start();

customer2.start();

}

}

修改之后如下:

import javax.sql.rowset.spi.SyncFactory;

 
class Cbank
{
     private static int s=2000;
     public synchronized static void sub(int m)
     {
           int temp=s;
           temp=temp-m;
          try {
                 Thread.sleep((int)(1000*Math.random()));
               }
           catch (InterruptedException e)  {              }
              s=temp;
              System.out.println("s="+s);
          }
    }
 
 
class Customer extends Thread
{
  public void   run()
  {
   forint i=1; i<=4; i++)
    Cbank.sub(100);
    }
 }
public class Thread3
{
 public static void main(String args[])
  {
   Customer customer1 = new Customer();
   Customer customer2 = new Customer();
   customer1.start();
   customer2.start();
  }
}

实验2 编程练习

利用多线程及同步方法,编写一个程序模拟火车票售票系统,共3个窗口,卖10张票,程序输出结果类似(程序输出不唯一,可以是其他类似结果)。

Thread-0窗口售:第1张票

Thread-0窗口售:第2张票

Thread-1窗口售:第3张票

Thread-2窗口售:第4张票

Thread-2窗口售:第5张票

Thread-1窗口售:第6张票

Thread-0窗口售:第7张票

Thread-2窗口售:第8张票

Thread-1窗口售:第9张票

Thread-0窗口售:第10张票

package xaincheng;

import java.nio.charset.MalformedInputException;

public class Demo {
public static void main(String[] args)
{
Mythread mythread= new Mythread();
Thread t1 = new Thread(mythread);
Thread t2 = new Thread(mythread);
Thread t3 = new Thread(mythread);
t1.start();
t2.start();
t3.start(); } } class Mythread implements Runnable{ int t=1;
boolean flag=true; public void run() { while(flag) {
try { Thread.sleep(500);
}
catch (InterruptedException e)
{
e.printStackTrace();
} synchronized (this) { if(t<=10){
System.out.println(Thread.currentThread().getName()+"窗口售:第"+t+"张票");
t++;
}
if(t>10){
flag=false;
} } }
}
}

实验总结:通过本学期对Java这门课程的学习收获了很多,也很感谢老师还有助教学长对我们无微不至的关心,也通过这次试验加深了对多线程的理解,知道了并发多线程的解决方法。

												

周强 201771010141面向对象程序设计(java)》第十七周学习总结的更多相关文章

  1. 201771010134杨其菊《面向对象程序设计java》第九周学习总结

                                                                      第九周学习总结 第一部分:理论知识 异常.断言和调试.日志 1.捕获 ...

  2. 201771010141 周强《面向对象程序设计(java)》第十三周学习总结

    实验目的与要求 (1) 掌握事件处理的基本原理,理解其用途: (2) 掌握AWT事件模型的工作机制: (3) 掌握事件处理的基本编程模型: (4) 了解GUI界面组件观感设置方法: (5) 掌握Win ...

  3. 扎西平措 201571030332《面向对象程序设计 Java 》第一周学习总结

    <面向对象程序设计(java)>第一周学习总结 正文开头: 项目 内容 这个作业属于哪个课程 https://www.cnblogs.com/nwnu-daizh/ 这个作业的要求在哪里 ...

  4. 201871010132-张潇潇《面向对象程序设计(java)》第一周学习总结

    面向对象程序设计(Java) 博文正文开头 项目 内容 这个作业属于哪个课程 https://www.cnblogs.com/nwnu-daizh/ 这个作业的要求在哪里 https://www.cn ...

  5. 201771010141 周强《面向对象设计 java》第十五周实验总结

    理论部分 ◼ JAR文件◼ 应用程序首选项存储◼ Java Web Start JAR文件: 1.Java程序的打包:程序编译完成后,程序员将.class文件压缩打包为.jar文件后,GUI界面程序就 ...

  6. 201871010115——马北《面向对象程序设计JAVA》第二周学习总结

    项目 内容 这个作业属于哪个课程 https://www.cnblogs.com/nwnu-daizh/ 这个作业的要求在哪里 https://www.cnblogs.com/nwnu-daizh/p ...

  7. 杨其菊201771010134《面向对象程序设计Java》第二周学习总结

    第三章 Java基本程序设计结构 第一部分:(理论知识部分) 本章主要学习:基本内容:数据类型:变量:运算符:类型转换,字符串,输入输出,控制流程,大数值以及数组. 1.基本概念: 1)标识符:由字母 ...

  8. 201871010124 王生涛《面向对象程序设计JAVA》第一周学习总结

    项目 内容 这个作业属于哪个课程 https://www.cnblogs.com/nwnu-daizh/ 这个作业的要求在哪里 https://edu.cnblogs.com/campus/xbsf/ ...

  9. 面向对象程序设计--Java语言第二周编程题:有秒计时的数字时钟

    有秒计时的数字时钟 题目内容: 这一周的编程题是需要你在课程所给的时钟程序的基础上修改而成.但是我们并不直接给你时钟程序的代码,请根据视频自己输入时钟程序的Display和Clock类的代码,然后来做 ...

随机推荐

  1. 记录下用axios遇到的问题

    这两天用axios做页面登录.遇到了N多问题,.首先是报Response to preflight request doesn't pass access control check: No 'Acc ...

  2. markdown首行缩进

    首行缩进两个字符:(每个表示一个空格,连续使用两个即可)   半角的空格  全角的空格

  3. mariadb笔记

    MariaDB or MySQL DDL:数据定义语言        DML:数据操纵语言 skip_name_resolve = on :跳过域名解析: MariaDB [(none)]> s ...

  4. reactjs-swiper react轮播图组件基于swiper

    react轮播图组件基于swiper demo地址:http://reactjs-ui.github.io/reactjs-swiper/simple.html 1. 下载安装 npm install ...

  5. js 批量提交数据

    // 批量提交数据 let pageSize = 100, total = dataTmp.length, list = dataTmp let totalPage = Math.ceil(total ...

  6. Flex 弹性盒基本语法

    网页布局(layout)是 CSS 的一个重点应用. 布局的传统解决方案,基于盒状模型,依赖 display 属性 + position属性 + float属性.它对于那些特殊布局非常不方便,比如,垂 ...

  7. 低版本IDE 打开 高版本 IDE 代码时 unit

    可以用单元别名 比如Vcl.Forms=Forms 来兼容.

  8. 后端程序员必会常用Linux命令总结

    1. 调整终端窗口大小: ctrl + '-'  缩小, ctrl + shift + '='  放大. 2. command --help 查询命令详细 或者 man command 3.ls命令, ...

  9. 将MD5值压缩成8位32进制生成8位长度的唯一英文数字组合字符串

    function str16to32($a){ for($a = md5( $a, true ), $s = '0123456789ABCDEFGHIJKLMNOPQRSTUV', $d = '', ...

  10. c#连接db2数据库

    .net项目要连接db2数据库,是要安装客户端的,否则是连接不上的: 若出现“未在本地计算机上注册‘ibmdadb2’提供程序” 解决办法: 1.先找到安装后的ibmdadb2.dll文件复制到c:\ ...