第九周课程总结&实验报告(七)

课程总结

1、继承Thread类创建线程:
Thread类本质上是实现了Runnable接口的一个实例,代表一个线程的实例。启动线程的唯一方法就是通过Thread类的start()实例方法。start()方法是一个native方法,它将启动一个新线程,并执行run()方法。这种方式实现多线程很简单,通过自己的类直接extend Thread,并复写run()方法,就可以启动新线程并执行自己定义的run()方法。例如: ``` public class MyThread extends Thread {   public void run() {    System.out.println("MyThread.run()");   } }

MyThread myThread1 = new MyThread();
MyThread myThread2 = new MyThread();
myThread1.start();
myThread2.start();

<table><tr><td bgcolor=yellow>2、实现Runnable接口创建线程:</td></tr></table>
如果自己的类已经extends另一个类,就无法直接extends Thread,此时,可以实现一个Runnable接口,如下:

public class MyThread extends OtherClass implements Runnable {
  public void run() {
   System.out.println("MyThread.run()");
  }
}

##线程同步
<table><tr><td bgcolor=yellow>1:同步代码块</td></tr></table>

synchronized(要同步的对象){
要同步的操作;
}


<table><tr><td bgcolor=yellow>2:同步方法</td></tr></table>

public synchronized void method(){
要同步的操作
}

<table><tr><td bgcolor=yellow>3: 同步准则</td></tr></table>

当编写synchronized块时,有几个简单的准则可以遵循,这些准则在避免死锁和性能危险的风险大有帮助:

(1) 使代码块保持简短,把不随线程变化的预处理和后处理移出synchronized块
(2) 不要阻塞。如 InputStream.read()
(3) 在持有锁的时候,不要对其他对象调用方法

###JAVA IO
<table><tr><td bgcolor=yellow>1.File类:</td></tr></table>

File类是对文件系统中文件以及文件夹进行封装的对象,可以通过对象的思想来操作文件和文件夹。 File类保存文件或目录的各种元数据信息,包括文件名、文件长度、最后修改时间、是否可读、获取当前文件的路径名,判断指定文件是否存在、获得当前目录中的文件列表,创建、删除文件和目录等方法。


<table><tr><td bgcolor=yellow>2.ava流操作有关的类或接口:</td></tr></table>
![](https://img2018.cnblogs.com/blog/1581881/201910/1581881-20191023213222915-1587486880.png)

<table><tr><td bgcolor=yellow>3.:Java流类图结构:</td></tr></table>
###IO流的分类

根据处理数据类型的不同分为:字符流和字节流
根据数据流向不同分为:输入流和输出流

![](https://img2018.cnblogs.com/blog/1581881/201910/1581881-20191023213541103-873223030.png)
![](https://img2018.cnblogs.com/blog/1581881/201910/1581881-20191023213550890-1254371245.png)
![](https://img2018.cnblogs.com/blog/1581881/201910/1581881-20191023213557627-1940691723.png)
![](https://img2018.cnblogs.com/blog/1581881/201910/1581881-20191023213603864-1452347146.png)

#实验报告:
完成火车站售票程序的模拟。
要求:
(1)总票数1000张;
(2)10个窗口同时开始卖票;
(3)卖票过程延时1秒钟;
(4)不能出现一票多卖或卖出负数号票的情况。

实验代码:

package 第九周实验;

class test implements Runnable {

static int ticket = 999;

public void run() {
	for (int i = 0; i < 1000; i++)
		synchronized (this) {
			if (ticket >= 0) {
				if (ticket == 0) {
					System.out.println(Thread.currentThread().getName() + "已无余票");
					break;
				} else {
					try {
						Thread.sleep(1000);

					} catch (InterruptedException e) {
						e.printStackTrace();
					}
					System.out.println(Thread.currentThread().getName() + "卖出一张票" + " " + "所剩余票为:" + ticket);
					ticket--;
				}

			}
		}
}

}

public class piao {
public static void main(String args[]) {
test t = new test();
Thread th1 = new Thread(t, "窗口一");
Thread th2 = new Thread(t, "窗口二");
Thread th3 = new Thread(t, "窗口三");
Thread th4 = new Thread(t, "窗口四");
Thread th5 = new Thread(t, "窗口五");
Thread th6 = new Thread(t, "窗口六");
Thread th7 = new Thread(t, "窗口七");
Thread th8 = new Thread(t, "窗口八");
Thread th9 = new Thread(t, "窗口九");
Thread th10 = new Thread(t, "窗口十");

	th1.start();
	th2.start();
	th3.start();
	th4.start();
	th5.start();
	th6.start();
	th7.start();
	th8.start();
	th9.start();
	th10.start();
}

}

![](https://img2018.cnblogs.com/blog/1581881/201910/1581881-20191023213948866-1472829366.png)
![](https://img2018.cnblogs.com/blog/1581881/201910/1581881-20191023213957658-2101265683.png)
![](https://img2018.cnblogs.com/blog/1581881/201910/1581881-20191023214010439-492406104.png)

###问题:在写这题时候出现了一票多售,或者只出售一个窗口,发现不能使用同步方法,而是使用同步代码块。

synchronized(要同步的对象){
要同步的操作;
}

###使用同步代码块后,以上代码将取值和修改中的操作进行了同步,所以不会出现卖票出现负数和一票多卖的错误,我发现就没有之前只出现一个窗口的错误了,但还是基本上一个窗口连续售票很多张后才出现其他窗口才开始售票,还有待加强,看是否还有改进的地方。
原文地址:https://www.cnblogs.com/hhl296738954/p/11729112.html