




版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
第九章Swing组件
学习目标能够正确创建组合框和列表,响应组合框和列表事件能够正确创建文本域和文本区,处理文本事件,利用文本组件实现数据的输入和输出能够在窗口中设置菜单,处理菜单项事件能够正确声明和创建对话框本章内容组合框与列表1文本组件2菜单组件3对话框4第一节组合框与列表组合框(JComboBox)是一个下拉式菜单,它有两种形式:不可编辑的和可编辑的对不可编辑的JComboBox,用户只能在现有的选项列表中进行选择对可编辑的JComboBox,用户既可以在现有选项中选择,也可以输入新的内容
JComboBox构造方法
JComboBox()创建一个没有任何可选项的默认组合框JComboBox(Object[]items)根据Object数组创建组合框,Object数组的元素即为组合框中的可选项下面命令将创建一个具有5个可选项的组合框:String[]itemList={"One","Two","Three","Four","Five"};JComboBox
jcb=newJComboBox(itemList); //使用数组itemList创建组合框JComboBox类中方法
voidaddItem(ObjectanObject)在末尾位置添加新的可选项ObjectgetItemAt(intindex)返回指定索引序号index处的可选项intgetItemCount()返回列表中的项数voidinsertItemAt(ObjectanObject,intindex)在index指定的位置添加新的可选项anObjectJComboBox类中方法
intgetSelectedIndex()返回列表中与给定项匹配的第一个选项的索引序号ObjectgetSelectedItem()返回当前所选项voidremoveAllItems()删除所有可选项voidremoveItem(ObjectanObject)删除由anObject指定的可选项voidremoveItemAt(intanIndex)删除由anIndex指定处的可选项示例
程序9-1每当用户在组合框jcb1中进行选择,被选中的选项就会通过下面命令被插入到组合框jcb2中的第一个位置:jcb2.insertItemAt(jcb1.getSelectedItem(),0);getSelectedItem()方法可获得用户的当前选项选项的索引序号是从0开始的
列表列表(JList)是可供用户进行选择的一系列可选项构造方法JList()构造一个空列表JList(Object[]listData)构造一个列表,列表的可选项由对象数组listData指定JList(Vector<?>listData)构造一个列表,使其显示指定Vector中的元素示例
下面的语句根据String数组构造一个包含4个可选项的列表:String[]data={"one","two","three","four"};JListdataList=newJList(data);
当用户在列表上进行选择时,将引发ListSelectionEvent事件在JList中提供了addListSelectionListener(ListSelectionListenerlistener)方法,用于注册对应的事件侦听程序在ListSelectionListener接口中,只包含一个方法:publicvoidvalueChanged(ListSelectionEvente);当列表的当前选项发生变化时,将会调用该方法JList类中的方法publicintgetSelectedIndex()返回所选项第一次出现的索引;如果没有所选项,则返回-1publicObjectgetSelectedValue()返回所选的第一个值,如果选择为空,则返回nullpublicvoidsetVisibleRowCount(intvisibleRowCount)设置不使用滚动条可以在列表中显示的首选行数示例程序9.2当程序运行时,在文本域中输入字符串,并单击按钮,可以动态地为列表添加可选项在列表对象创建之后,也可以使用JList中定义的setModel(ListModelmodel)方法设置新的ListModel。列表对象本身并不带滚动条,但是当列表可选项较多时,可以将列表对象放入JScrollPane中以提供滚动功能列表既支持单项选择也支持多项选择setSelectionMode(intselectionMode)方法中参数selectionMode可以是下列常量:ListSelectionModel.SINGLE_SELECTION只能进行单项选择ListSelectionModel.SINGLE_INTERVAL_SELECTION可多项选择,但多个选项必须是连续的ListSelectionModel.MULTIPLE_INTERVAL_SELECTION多项选择,多个选项可以是间断的,这是选择模式的默认值第二节文本组件文本组件可用于显示信息和提供用户输入功能在Swing中提供了文本域(JTextField)、口令输入域(JPasswordField)、文本区(JTextArea)等多个文本组件这些文本组件都有一个共同的父类——JTextComponentJTextComponent中定义的方法StringgetSelectedText()从文本组件中提取被选中的文本内容String getText()从文本组件中提取所有文本内容StringgetText(intoffs,intlen)从文本组件中提取指定范围的文本内容voidselect(intselectionStart,intselectionEnd)在文本组件中选中指定的起始和结束位置之间的文本内容voidselectAll()在文本组件中选中所有文本内容voidsetEditable(booleanb)设置为可编辑或不可编辑状态voidsetText(Stringt)设置文本组件中的文本内容voidsetDocument(Documentdoc)设置文本组件的文档voidcopy()复制选中的文本到剪贴板voidcut()剪切选中的文本到剪贴板voidpaste()将剪贴板的内容粘贴到当前位置JComponent类中的常用方法publicbooleanrequestFocusInWindow()请求当前组件获得输入焦点文本域文本域是一个单行的文本输入框,可用于输入少量文本
构造方法JTextField()构造一个空文本域JTextField(intcolumns)构造一个具有指定列数的空文本域,int型参数columns指定文本域的列数文本域JTextField(Stringtext)构造一个显示指定初始字符串的文本域,String型参数text指定要显示的初始字符串JTextField(Stringtext,intcolumns)构造一个具有指定列数、并显示指定初始字符串的文本域,String型参数text指定要显示的初始字符串,int型参数columns指定文本域的列数文本域的常用方法voidaddActionListener(ActionListenerl)添加指定的操作侦听器,接收操作事件voidremoveActionListener(ActionListenerl)移除指定的操作侦听器,不再接收操作事件voidsetFont(Fontf)设置当前字体常用方法voidsetHorizontalAlignment(intalignment)设置文本的水平对齐方式,有效值包括:JTextField.LEFTJTextField.CENTERJTextField.RIGHTJTextField.LEADINGJTextField.TRAILINGintgetColumns()返回文本域的列数示例JTextFieldtf=newJTextField("SingleLine",30);这条命令创建一个列数为30、初始字符串为“SingleLine”的文本域在构造方法中所指定的列数,是一个希望的数值,由于组件的大小和位置通常是由布局管理器决定的,因此,指定的这些数据很有可能被忽略可以用setEditable(boolean)方法将文本域设定为可编辑或不可编辑状态文本区文本区是一个多行多列的文本输入框常用的构造方法JTextArea():构造一个空文本区JTextArea(Stringtext):构造一个显示指定初始字符串的文本区,String型参数text指定要显示的初始字符串JTextArea(introws,intcolumns):构造一个具有指定行数和列数的空文本区,int型参数rows和columns分别指定文本区的行数和列数JTextArea(Stringtext,introws,intcolumns):构造一个具有指定行数和列数、并显示指定初始字符串的文本区,String型参数text指定要显示的初始字符串,int型参数rows和columns指定文本区的行数和列数文本区JTextAreata=newJTextArea("Initialtext",4,30);创建一个4行、30列、显示初始字符串“Initialtext”的文本区构造方法中指定的行数和列数只是希望的数值,文本区的大小仍然是由布局管理器决定的文本区本身不带滚动条,由于文本区内显示的内容通常比较多,因此一般将其放入滚动窗格JScrollPane中文本区常用方法voidappend(Stringstr)将指定文本str追加到文本区voidinsert(Stringstr,intpos)将指定文本str插入到文本区的特定位置pos处voidreplaceRange(Stringstr,intstart,intend)用指定文本str替换文本区中从起始位置start到结尾位置end的内容程序9.3第三节菜单组件菜单也是最常用的GUI组件之一Swing包中提供了多种菜单组件JMenuBarJMenuItemJmenuJCheckBoxMenuItemJRadioButtonMenuItemJPopupMenu等菜单有下拉式菜单和弹出式菜单两种,本节介绍下拉式菜单菜单栏及菜单菜单栏是窗口中的主菜单,用来包容一组菜单菜单栏只有一种构造方法,即JMenuBar()JFrame、JApplet和JDialog等类中都定义了setJMenuBar(JMenuBarmenu)方法,可以把菜单栏放到窗口的上方JFrameframe=newJFrame(“MenuDemo”); //菜单窗口标题是“MenuDemo”JMenuBarmb=newJMenuBar(); //创建菜单栏frame.setJMenuBar(mb); //放到框架的上方菜单的常用构造方法JMenu()构造没有文本的新菜单JMenu(Strings)构造具有指定标签的新菜单,String型参数s指定了菜单上的文本JMenu(Strings,booleanb)构造具有指定标签的新菜单,指示该菜单是否可以分离例9.1创建两个菜单的示例菜单项常用的菜单项构造方法JMenuItem()创建不带有设置文本或图标的菜单项JMenuItem(Iconicon)创建一个只显示图标的菜单项,图标由Icon型参数icon指定JMenuItem(Stringtext)创建一个只显示文本的菜单项,文本由String型参数text指定JMenuItem(Stringtext,Iconicon)创建一个同时显示文本和图标的菜单项,文本由String型参数text指定,图标由Icon型参数icon指定JMenuItem(Stringtext,intmnemonic)创建一个显示文本并且有快捷键的菜单项,文本由String型参数text指定,快捷键由int型参数mnemonic指定添加菜单项示例快捷键也可以在菜单项被创建之后,通过setMnemonic(charmnemonic)方法进行设置在类中还定义了一个setAccelerator(KeyStrokekeyStroke)方法,使用该方法可以为菜单项设置加速键JMenuItemmenuItem=newJMenuItem("Open...");menuItem.setMnemonic(KeyEvent.VK_O);menuItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_1,ActionEvent.ALT_MASK));在Menu类中定义有addSeparator()和insertSeparator(intindex)方法可以在某个菜单的各个菜单项间加入分隔线menu1.add(mi1);menu1.add(mi2);menu1.addSeparator();menu1.add(mi3);菜单项中还可以含有菜单项,组成嵌套的菜单当菜单中的菜单项被选中时,将会引发一个ActionEvent事件通常需要为菜单项注册ActionListener以便对事件作出响应menuItem.addActionListener(this); //注册侦听器程序9.4复选菜单项和单选菜单项复选菜单项和单选菜单项是两种特殊的菜单项,在复选菜单项前面有一个小方框,在单选菜单项前面有一个小圆圈可以对这两类菜单项进行选中或不选中的操作复选菜单项构造方法JCheckBoxMenuItem()创建一个未设置文本或图标、最初也未选定的复选框菜单项JCheckBoxMenuItem(Iconicon)创建一个有图标、最初未被选定的复选框菜单项JCheckBoxMenuItem(Stringtext)创建一个带文本、最初未被选定的复选框菜单项复选菜单项构造方法JCheckBoxMenuItem(Stringtext,booleanb)创建具有指定文本和选择状态的复选框菜单项JCheckBoxMenuItem(Stringtext,Iconicon)创建带有指定文本和图标、最初未被选定的复选框菜单项JCheckBoxMenuItem(Stringtext,Iconicon,booleanb)创建具有指定文本、图标和选择状态的复选框菜单项单选菜单项的构造方法JRadioButtonMenuItem()创建一个未设置文本或图标的单选按钮菜单项。JRadioButtonMenuItem(Iconicon)创建一个带图标的单选按钮菜单项JRadioButtonMenuItem(Iconicon,booleanselected)创建一个具有指定图标和选择状态的单选按钮菜单项,但无文本JRadioButtonMenuItem(Stringtext):创建一个带文本的单选按钮菜单项单选菜单项的构造方法JRadioButtonMenuItem(Stringtext,booleanselected)创建一个具有指定文本和选择状态的单选按钮菜单项JRadioButtonMenuItem(Stringtext,Iconicon)创建一个具有指定文本和图标的单选按钮菜单项JRadioButtonMenuItem(Stringtext,Iconicon,booleanselected)创建一个具有指定的文本、图标和选择状态的单选按钮菜单项示例JCheckBoxMenuItemmi1=newJCheckBoxMenuItem(“Persistent”);//显示Persistent、初态为未选中JCheckBoxMenuItemmi2=newJCheckBoxMenuItem(“transient”,true);//显示transient、初态为选中当菜单项的状态发生改变时,会引发ItemEvent事件,可以使用ItemListener中的itemStateChanged()对此事件进行响应通常在建立菜单系统时,可以首先创建一个菜单栏,并通过setMenuBar()方法将其放入某个框架中然后创建若干个菜单,通过add()方法将它们加入菜单栏中最后创建各个菜单项,通过add()方法将它们加入不同的菜单中第四节对话框对话框是一个临时的可移动窗口,且要依赖于其他窗口当它所依赖的窗口消失或最小化时,对话框也将消失当窗口还原时,对话框会自动恢复一般地,要先创建一个窗口类,再创建一个对话框类,且让对话框依附于窗口对话框分为强制型和非强制型两种强制型对话框被关闭之前,其他窗口无法接收任何形式的输入,也就是该对话过程不能中断这样的窗口也称为模式窗口非强制型对话框可以中断对话过程,去响应对话框之外的事件对话框的构造方法JDialog(Dialogowner)创建一个没有标题但将指定的对话框作为其所有者的无模式对话框JDialog(Dialogowner,booleanmodal)创建一个没有标题但有指定所有者的对话框,boolean型参数modal指定对话框是有模式或无模式JDialog(Dialogowner,Stringtitle)创建一个具有指定标题和指定所有者的无模式对话框对话框的构造方法JDialog(Dialogowner,Stringtitle,booleanmodal)创建一个具有指定标题和指定所有者的对话框,boolean型参数modal指定对话框是有模式或无模式JDialog(Frameowner)创建一个没有标题但将指定的框架作为其所有者的无模式对话框JDialog(Frameowner,booleanmodal)创建一个没有标题但有指定所有者的对话框,boolean型参数modal指定对话框是有模式或无模式对话框的构造方法JDialog(Frameowner,Stringtitle)创建一个具有指定标题和指定所有者框架的无模式对话框。JDialog(Frameowner,Stringtitle,booleanmodal)创建一个具有指定标题和指定所有者框架的对话框,boolean型参数modal指定对话框是有模式或无模式对话框的构造方法构造方法中的Dialog型或Frame型的参数,指定了对话框的拥有者,也就是它的依赖窗口JDialogdialog=newJDialog(frame,"Dialog",true);创建了一个标题为“Dialog”的模式对话框,该对话框为框架frame所拥有刚刚创建的对话框是不可见的,需要调用setVisible(true)方法才能将其显示出来程序9.5标准对话框在Swing中还提供了用于显示标准对话框的JOptionPane类在JOptionPane类中定义了多个showXxxDialog形式的静态方法,可以分为以下4种类型:showConfirmDialog:确认对话框,显示问题,要求用户进行确认(yes/no/cancel)showInputDialog:输入对话框,提示用户进行输入showMessageDialog:信息对话框,显示信息,告知用户发生了什么情况showOptionDialog:选项对话框,显示选项,要求用户进行选择showXxxDialog方法的参数类型ComponentparentComponent对话框的父窗口对象,其屏幕坐标将决定对话框的显示位置Stringtitle对话框的标题Objectmessage显示在对话框中的描述信息intmessageType对话框所传递的信息类型intoptionType对话框上按钮的类型Object[]options对话框上的选项Iconicon对话框上显示的装饰性图标,如果没有指定,则根据messageType参数显示默认图标ObjectinitialValue初始选项或输入值文件对话框文件对话框是专门用于对文件(或目录)进行浏览和选择的对话框常用的构造方法JFileChooser():构造一个指向用户默认目录的文件对话框JFileChooser(FilecurrentDirectory):使用给定的File作为路径来构造一个文件对话框JFileChooser(StringcurrentDirectoryPath):构造一个使用给定路径的文件对话框刚刚创建的文件对话框是不可见的,可以调用以下方法将其显示出来:showOpenDialog(Componentparent):弹出一个"打开"文件对话框showSaveDialog(Componentparent):弹出一个"保存"文件对话框程序9.6ThankYou!第十章多线程
学习目标能够叙述线程和多线程的概念,线程各种状态之间转换的条件,线程的优先级能够使用Thread类和Runnabe接口创建线程能够对线程进行控制,实现线程之间的互斥和同步本章主要内容线程和多线程12线程的基本控制3创建线程线程的互斥4线程的同步5线程的概念程序是一段静态的代码,它是应用程序执行的蓝本一个进程既包括其所要执行的指令,也包括了执行指令所需的任何系统资源,如CPU、内存空间、I/O端口等,不同进程所占用的系统资源相对独立线程是进程执行过程中产生的多条执行线索,是比进程单位更小的执行单位线程的结构在Java中,线程由3部分组成:虚拟CPU,封装在java.lang.Thread类中,它控制着整个线程的运行执行的代码,传递给Thread类,由Thread类控制按序执行处理的数据,传递给Thread类,是在代码执行过程中所要处理的数据当一个线程被构造时,它由构造方法参数、执行代码、操作数据来初始化一个线程所执行的代码与其他线程可以相同也可以不同一个线程访问的数据与其他线程可以相同也可以不同多线程的优势使用多线程可以在线程间直接共享数据和资源,而多进程之间不能做到这一点使用多线程适合于开发有多种交互接口的程序多线程的机制可以减轻编写交互频繁、涉及面多的程序的困难,如侦听网络端口的程序线程的状态线程一共有4种状态,分别是新建、可运行状态、死亡及阻塞新建线程对象刚刚创建,还没有启动,此时还处于不可运行状态此时刚创建的线程处于新建状态,但已有了相应的内存空间以及其它资源可运行状态此时的线程已经启动,线程可能正在运行,也可能没有运行,只要CPU一空闲,马上就会运行可以运行但没在运行的线程都排在一个队列中,这个队列称为就绪队列可运行状态中,正在运行的线程处于运行状态,等待运行的线程处于就绪状态一般地,单CPU情况下,最多只有一个线程处于运行状态,可能会有多个线程处于就绪状态调用线程的start()方法可使线程处于“可运行”状态死亡线程死亡的原因有两个一是run()方法中最后一个语句执行完毕二是当线程遇到异常退出时便进入了死亡状态阻塞一个正在执行的线程因特殊原因,被暂停执行,就进入阻塞状态阻塞时线程不能进入就绪队列排队,必须等到引起阻塞的原因消除,才可重新进入队列排队引起阻塞的原因很多,不同原因要用不同的方法解除sleep()和wait()是两个常用的引起阻塞的方法中断线程在程序中常常调用interrupt()来终止线程interrupt()不仅可中断正在运行的线程,而且也能中断处于blocked状态的线程interrupt()会抛出InterruptedException异常测试线程是否被中断的方法voidinterrupt()向一个线程发送一个中断请求,同时把这个线程的“interrupted”状态置为true。若该线程处于“blocked”状态,会抛出InterruptedException异常staticbooleaninterrupted()检测当前线程是否已被中断,并重置状态“interrupted”值。即如果连续两次调用该方法,则第二次调用将返回falsebooleanisInterrupted()检测当前线程是否已被中断,不改变状态“interrupted”值第二节创建线程创建线程有两种方法继承Thread类创建线程实现Runnable接口创建线程继承Thread类java.lang.Thread是Java中用来表示线程的类如果将一个类定义为Thread的子类,那么这个类的对象就可以用来表示线程类Thread中典型的构造方法Thread(ThreadGroupgroup,Runnabletarget,Stringname)name作为新线程的名称,且是线程组group中的一员target必须实现接口Runnable,它是另一个线程对象创建线程的过程从Thread类派生出一个子类,在类中实现run()classLefthandextendsThread{ publicvoidrun(){……} //线程体}然后用该类创建一个对象Lefthandleft=newLefthand();用start()方法启动线程left.start();程序10.1实现Runnable接口创建线程Runnable是Java中用以实现线程的接口,从任何实现线程功能的类都必须实现该接口Thread类实际上就是因为实现了Runnable接口,所以它的子类才相应具有线程功能Runnable接口中只定义了一个方法就是run()方法,也就是线程体用Runnable()接口实现多线程时,也必须实现run()方法,也需要使用start()启动线程编写线程体publicclassxyzimplementsRunnable{ inti; publicvoidrun(){ while(true){
System.out.println("Hello"+i++); } }}利用类xyz可以构造一个线程Runnabler=newxyz();Threadt=newThread(r);程序10.2创建线程两种方法的适用条件适用于采用实现Runnable接口方法的情况因为Java只允许单继承,如果一个类已经继承了Thread,就不能再继承其他类,在一些情况下,这就被迫采用实现Runnable的方法另外,由于原来的线程采用的是实现Runnable接口的方法,可能会出于保持程序风格的一贯性而继续使用这种方法创建线程两种方法的适用条件适用于采用继承Thread方法的情况当一个run()方法置于Thread类的子类中时,this实际上引用的是控制当前运行系统的Thread实例,所以,代码不必写得像下面这样繁琐:Thread.currentThread().getState();而可简单地写为:getState();可以直接调用Thread类中的方法,代码直观,所以许多Java程序员愿意使用继承Thread的方法第三节线程的基本控制线程的启动要使线程真正在Java环境中运行,必须通过方法start()来启动start()方法也在Thread类中线程的操作方法start()启动线程对象,让线程从新建状态转为就绪状态run()用来定义线程对象被调度之后所执行的操作,用户必须重写run()方法yield()强制终止线程的执行isAlive()测试当前线程是否在活动sleep(intmillsecond)使线程休眠一段时间,时间长短由millsecond决定,单位为毫秒voidwait()使线程处于等待状态线程的调度虽然就绪线程已经可以运行,但这并不意味着这个线程一定能够立刻运行CPU在同一时间只能分配给一个线程做一件事那么当有多于一个的线程工作时,CPU是如何分配的?这就是线程的调度问题在Java中,线程调度通常是抢占式,而不是时间片式抢占式调度是指可能有多个线程准备运行,但只有一个在真正运行一个线程获得执行权,这个线程将持续运行下去,直到它运行结束或因为某种原因而阻塞,再或者有另一个高优先级线程就绪,最后一种情况称为低优先级线程被高优先级线程所抢占线程调度采用的优先级策略优先级高的先执行,优先级低的后执行每个线程创建时都会被自动分配一个优先级,默认时,继承其父类的优先级任务紧急的线程,其优先级较高同优先级的线程按“先进先出”的调度原则与线程优先级有关的静态量MAX_PRIORITY:最高优先级,值为10MIN_PRIORITY:最低优先级,值为1NORM_PRIORITY:默认优先级,值为5有关优先级的常用方法voidsetPriority(intnewPriority)重置线程优先级intgetPriority()获得当前线程的优先级staticvoidyield()暂停当前正在执行的线程,即让当前线程放弃执行权线程被阻塞的原因可能是因为执行了Thread.sleep()调用,故意让它暂停一段时间也可能是因为需要等待一个较慢的外部设备例如磁盘或用户操作的键盘线程队列所有被阻塞的线程按次序排列,组成一个阻塞队列所有就绪但没有运行的线程则根据其优先级排入一个就绪队列当CPU空闲时,如果就绪队列不空,队列中第一个具有最高优先级的线程将运行当一个线程被抢占而停止运行时,它的运行态被改变并放到就绪队列的队尾同样,一个被阻塞的线程就绪后通常也放到就绪队列的队尾结束线程当一个线程从run()方法的结尾处返回时,它自动消亡并且不能再被运行,可以将其理解为自然死亡另一种情况是遇到异常使得线程结束,可以将其理解为强迫死亡还可以使用interrupt()方法中断线程的执行查询线程状态在程序代码中,可以利用Thread类中的静态方法currentThread()来引用正在运行的线程有时候可能不知道一个线程的运行状态,这时可以使用方法isAlive()来获取一个线程是否还在活动状态的信息活动状态不意味着这个线程正在执行,而只说明这个线程已被启动挂起线程暂停一个线程也称为挂起在挂起之后,必须重新唤醒线程进入运行挂起线程的方法——sleep()方法sleep()用于暂时停止一个线程的执行挂起唤醒线程不是休眠期满后就立刻被唤醒,因为此时其他线程可能正在执行重新调度只在以下几种情况下才会发生被唤醒的线程具有更高的优先级正在执行的线程因为其他原因被阻塞程序处于支持时间片的系统中挂起线程的方法wait()和notify()/notifyAll()方法wait()方法导致当前的线程等待,直到其他线程调用此对象的notify()方法或notifyAll()方法,才能唤醒线程join()方法join()将引起现行线程等待,直至方法join()所调用的线程结束比如在线程B中调用了线程A的join()方法,直到线程A执行完毕后,才会继续执行线程B可以想像成将线程A加入到当前线程B中第四节线程的互斥一些同时运行的线程需要共享数据此时,每个线程就必须要考虑与它一起共享数据的其他线程的状态与行为,否则的话就不能保证共享数据的一致性,因而也就不能保证程序的正确性栈的示例栈具有“后进先出”模式,它使用下标值idx表示栈中下一个放置元素的位置有两个独立的线程A和B都具有对这个类的同一个对象的引用,线程A负责入栈,线程B负责出栈要求线程A放入栈中的数据都要由线程B读出,不重不漏假设此时栈中已经有字符1和2,当前线程A要入栈一个字符3,调用push(3),执行了语句data[idx]=c;后被其他线程抢占了,此时尚未执行idx++语句。故idx指向最后入栈的字符的下标data123idx=2^如果此时线程A马上被唤醒,可以继续修正idx的值,从而完成一次完整的入栈操作如若不然,入栈操作执行了一半若恰巧线程B此时正占有CPU,调用pop(),执行出栈操作,则它返回的字符是2,因为它先执行idx--语句,idx的值变为1,返回的是data[1]处的字符,即字符2字符3被漏掉了多线程访问共享数据时通常会引起问题产生这种问题的原因是对共享资源访问的不完整性需要寻找一种机制来保证对共享数据操作的完整性这种完整性称为共享数据操作的同步共享数据叫做条件变量锁定标志可以禁止线程在完成代码关键部分时被切换这个关键代码部分,对于线程A就是入栈操作及下标值增加这两个动作,对于线程B就是下标值递减及出栈操作这两个动作它们要么一起完成,要么都不执行在Java中,提供了一个特殊的锁定标志来处理共享数据的访问对象的锁定标志引入“对象互斥锁”的概念,也称为监视器使用它来实现不同线程对共享数据操作的同步“对象互斥锁”阻止多个线程同时访问同一个条件变量Java可以为每一个对象的实例配有一个“对象互斥锁”实现“对象互斥锁”的方法用关键字synchronized来声明一个方法或一段代码块,该方法或代码块在执行时会获取对象实例的内置锁,其他线程必须等待锁的释放才能访问该方法或代码块中的共享数据使用关键字volatile来声明一个共享数据(变量)。但是,使用volatile关键字只能保证数据的可见性和有序性,无法实现对共享数据的原子操作,因此不能完全替代使用synchronized实现同步锁定标志示例classstack{ intidx=0; chardata[]=newchar[6]; publicvoidpush(charc){ synchronized(this){//增加同步标志 data[idx]=c;
idx++; } }}锁定标志方法publiccharpop(){ synchronized(this){ //增加同步标志
idx--; returndata[idx]; }}synchronized(this)现在pop()和push()操作的部分增加了一个对synchronized(this)的调用,在第一个线程拥有锁定标记时,如果另一个线程企图执行synchronized(this)中的语句时,它将从对象this中索取锁定标记因为这个标记不可得,故该线程不能继续执行实际上这个线程将加入一个等待队列,该等待队列与对象锁定标志相连,当标志被返还给对象时,等待标志的第一个线程将得到该标志并继续运行因为等待一个对象的锁定标志的线程要等到持有该标志的线程
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 《小英雄雨来》观后感(合集15篇)
- 年产200吨医药中间体项目可行性研究报告(模板范文)
- 家医上门服务的政策支持与执行策略
- 海洋科技创新的发展框架与路径
- 新疆乌鲁木齐市实验学校2023-2024学年高三上学期1月月考生物含解析
- 小学均衡发展教育班会
- 珠海艺术职业学院《计算机导论》2023-2024学年第二学期期末试卷
- 皖江工学院《广告策划与制作》2023-2024学年第二学期期末试卷
- 心理学知识普及课件
- 开封职业学院《分离工程》2023-2024学年第二学期期末试卷
- 山东省济南市重点中学2025届高考生物二模试卷含解析
- 新版gmp实务教程试题及答案
- 2025年下半年度中铁特货物流股份限公司招聘毕业生三易考易错模拟试题(共500题)试卷后附参考答案
- 2025年辽宁省各市农村电力服务有限公司招聘笔试参考题库附带答案详解
- 江西省赣州市2025届高三二模语文试题及参考答案
- 消化内科笔试试题及答案
- 2025年山东省青岛市崂山区中考数学一模试题(原卷版+解析版)
- 嘉峪关2025年嘉峪关市事业单位引进50名高层次和急需紧缺人才(含教育系统)笔试历年参考题库附带答案详解
- 玉器代销合同协议书范本
- 正比例函数性质课件
- 铁路退休人员乘车优惠政策
评论
0/150
提交评论