第十四章 Java多线程(1.2)

售票问题

多个线程访问同一个资源时会发生死锁问题。

package com.bennett.test1024;

/**
 * @Version: 1.0
 * @Description:售票问题
 * @Author: bennett
 * @Date: 2021年10月25日 下午9:23:23
 */
public class TicketThread {

	public static void main(String[] args) {
		Ticket ticket = new Ticket();
		new salMan("售票员1",ticket).start();
		new salMan("售票员2",ticket).start();
		new salMan("售票员3",ticket).start();
		new salMan("售票员4",ticket).start();
	}
}
class Ticket{
	private int i = 8;
	
	public int sal() {
		System.out.println("票"+i);
		i--;
		return i;
	}
}
class salMan extends Thread{
	private String name;
	Ticket ticket;//定义同一份资源
	
	public salMan(String name, Ticket ticket) {
		super();
		this.name = name;
		this.ticket = ticket;
	}
	@Override
	public void run() {
		synchronized (ticket) {
			System.out.println(this.name+"在销售---");
			ticket.sal();
		}
	}
}

运行结果:
加锁的结果

售票员1在销售---8
售票员4在销售---7
售票员3在销售---6
售票员2在销售---5

未加锁的结果

售票员1在销售---
售票员3在销售---
售票员4在销售---
售票员2在销售---8888

两线程死锁问题

两个线程共享统一资源的不同部分(A和B),线程1先使用A,线程先使用B,这样就会发生死锁。

package com.bennett.test1025;

/**
 * @Version: 
 * @Description:两个线程的死锁
 * 				有两个锁,自己持有一个再去申请另外一个
 * @Author: bennett
 * @Date: 2021年10月25日 下午9:49:54
 */
public class TwoDeadThread {
  static Object o1 = new Object();
  static Object o2 = new Object();
  public static void main(String[] args) {
      Thread s1 = new Thread(new Lock1());
      Thread s2 = new Thread(new Lock2());
      s1.start();
      s2.start();

  }
}
class Lock1 implements Runnable{
  @Override
  public void run() {
      synchronized (TwoDeadThread.o1){
          try {
              System.out.println("get o1");
              Thread.sleep(1000);
          } catch (InterruptedException e) {
              e.printStackTrace();
          }
          synchronized (TwoDeadThread.o2){
              System.out.println("get o2");
          }
      }
  }
}

class Lock2 implements Runnable{
  @Override
  public void run() {
      synchronized (TwoDeadThread.o2){
          try {
              System.out.println("get o2");
              Thread.sleep(1000);
          } catch (InterruptedException e) {
              e.printStackTrace();
          }
          synchronized (TwoDeadThread.o1){
              System.out.println("get o1");
          }
      }
  }
}

1a2b3c问题

package com.bennett.test1025;
import java.util.Random;

public class ConcurretPrintTest {
	
	static class ThreadA extends Thread {
		private Object flag;

		public ThreadA(Object flag) {
			this.flag = flag;
		}

		private String[] array = "1,2,3".split(",");

		@Override
		public void run() {
			synchronized (flag) {
				for (String string : array) {
					System.out.print(string + ",");
					try {
						Thread.sleep(new Random().nextInt(50));
					} catch (InterruptedException e) {
						e.printStackTrace();
					}
					// 通知线程B工作
//					flag.notify();// 随机唤醒对象监视器(阻塞的线程池)中的任意1个线程
//					System.out.println("ThreadA唤醒其它线程");
					 flag.notifyAll();//唤醒对象监视器(阻塞的线程池)中所有线程
					// 自己停止
					try {
						flag.wait();
					} catch (InterruptedException e) {
						e.printStackTrace();
					}
				}
			}
		}
	}
	static class ThreadB extends Thread{
		private Object flag;
		private String[] array="a,b,c".split(",");
		
		public ThreadB(Object flag) {
			this.flag = flag;
		}

		@Override
		public void run() {
			synchronized(flag) {
				try {
//					System.out.println("ThreadB锁定");
					flag.wait();//让使用这个信号灯线程等待
				} catch (InterruptedException e1) {
					e1.printStackTrace();
				}
//				System.out.println("ThreadB唤醒");
				for (String string : array) {
					System.out.print(string+",");
					try {
						Thread.sleep(new Random().nextInt(50));
					} catch (InterruptedException e) {
						e.printStackTrace();
					}
//				通知线程A工作
//				自己停止
					flag.notify();
//				自己停止
					try {
						flag.wait();
					} catch (InterruptedException e) {
						e.printStackTrace();
					}
				}
			}
		}
	}
	public static void main(String[] args) {
		Object xiHaoDeng=new Object();
		new ThreadB(xiHaoDeng).start();
		new ThreadA(xiHaoDeng).start();
	}
}

多线程考拷贝文件

package com.bennett.test1012;

import java.io.IOException;
import java.io.RandomAccessFile;
import java.util.concurrent.CountDownLatch;

/**
 * @version:
 * @Description:拷贝文件
 * @author gxd
 * @date: 2021年10月12日 下午3:43:50
 */ 
public class CopyFilesByRunnableDemo extends Thread {
    private final int NUMBER = 1024;//8kb==8192
    //等待线程
    CountDownLatch downLatch;
    //随机访问文件类
    RandomAccessFile oldFile;
    RandomAccessFile newFile;
    String oldRUL;
    String newRUL;
    long start;
    long end;
//	构造方法
    public CopyFilesByRunnableDemo(String oldRUL, String newRUL, long start, long end, CountDownLatch downLatch) {
        this.oldRUL = oldRUL;
        this.newRUL = newRUL;
        this.start = start;
        this.end = end;
        this.downLatch = downLatch;
    }

    @Override
    public void run() {
        try {
            System.out.println(Thread.currentThread().getName() + "线程启动了...");
            //需要复制的长度
            long len = end - start;
            //已经复制的长度
            long length = 0;
            //需要复制的资源
            oldFile = new RandomAccessFile(oldRUL, "rw");
            newFile = new RandomAccessFile(newRUL, "rw");

            oldFile.seek(start);//跳过的字节
            newFile.seek(start);
            byte[] bytes = new byte[NUMBER];
            while (true) {
                if ((len - length) <= NUMBER) {
                    oldFile.read(bytes, 0, (int) (len - length));
                    newFile.write(bytes, 0, (int) (len - length));
                    break;
                } else {
                    oldFile.read(bytes);
                    newFile.write(bytes);
                    length += NUMBER;
                }
            }
            oldFile.close();
            newFile.close();
            downLatch.countDown();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}
package com.bennett.test1012;

import java.io.File;
import java.util.concurrent.CountDownLatch;

/**
 * @version:
 * @Description:文件拷贝测试类
 * @author gxd
 * @date: 2021年10月12日 下午4:02:33
 */ 
public class CopyFilesTest {
	 public static void main(String[] args) {
	        String oldURL = "E:/BaiduNetdiskDownload/软件设计师历年上午试卷.docx";
			String newURL = "E:/file2.docx";
	        File oldFile = new File(oldURL);
	        //获取文件的长度
	        long lengthFile = oldFile.length();
	        //要开启的线程数
	        int threadCount = 4;
	        //每个线程需要的平均长度
	        long meanLen = lengthFile / threadCount;
	        //开始时间
	        long start;
	        //结束时间
	        long end;
	        //记录时间
	        long startCurrent = System.currentTimeMillis();

	        CountDownLatch downLatch = new CountDownLatch(threadCount);

	        for (int i = 0; i < threadCount; i++) {
	            if (i == threadCount - 1L) {
	                start = i * meanLen;
	                end = lengthFile;
	                new CopyFilesByRunnableDemo(oldURL, newURL, start, end, downLatch).start();
	            } else {
	                start = i * meanLen;
	                end = start + meanLen - 1L;
	                new CopyFilesByRunnableDemo(oldURL, newURL, start, end, downLatch).start();
	            }
	        }
	        try {
	            //等待线程结束
	            downLatch.await();//调用await()方法的线程会被挂起,它会等待直到threadCount值为0才继续执行
	        } catch (InterruptedException e) {
	            e.printStackTrace();
	        }
	        long entCurrent = System.currentTimeMillis();
	        System.out.println("文件拷贝使用时间(毫秒):"+(entCurrent - startCurrent));
	    }
}

拷贝文件

package com.bennett.test1008;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStream;

/**
 * @version:
 * @Description:文件拷贝
 * @author gxd
 * @date: 2021年10月12日 下午2:54:13
 */ 
public class FileCopy {
	//javaAdvance/bin>> java com.bennett.test1008.FileCopy test1.txt test4.txt
//	E:\myspace\TrainingSet\ClassNotesAndKnowledgeSummary\Java\Test\JavaAdvance\bin>>  java com.bennett.test1008.FileCopy D:\fileTest\test1.txt test3.txt
	public static void main(String[] args) {
		if(args.length!=2) {
			System.out.println("请指定源文件和目标文件");
			return;
		}
		if(args[0]==null) {
			System.out.println("请指定源文件");
			return;
		}
		File src=new File(args[0]);
		if(!src.exists()) {
			System.out.println("源文件不存在");
			return;
		}
		if(args[1]==null) {
			System.out.println("请指定目标文件");
			return;
		}
		File dest=new File(args[1]);
		
		if(dest.getParentFile()!=null && !dest.getParentFile().exists()) {
			System.out.println(dest.getAbsolutePath());
			dest.getParentFile().mkdirs();
		}
		try(
			InputStream is=new FileInputStream(src);
			OutputStream os=new FileOutputStream(dest,false);
			){
			int i=0;
			byte[] buffer=new byte[1024];
			while((i=is.read(buffer))!=-1) {
				os.write(buffer,0,i);
				System.out.println(i);
				os.flush();
			}
			os.close();;
			is.close();;
			System.out.println("复制成功");
			
		}catch (Exception e) {
		}
	}
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值