import java.io.File;
import java.io.IOException;
/**
* File提供了对当前文件系统中文件的部分操作
*
*
*/
public class FileDemo {
public static void main(String[] args) throws IOException {
File file = new File("src/abc.txt");
//创建文件
try {
file.createNewFile();
} catch (IOException e) {
e.printStackTrace();
}
//判断文件的属性,都会返回boolean类型的值
file.canExecute();
file.canRead();
file.canWrite();
//判断当前文件是否存在
System.out.println(file.exists());
//获取文件的名称
System.out.println(file.getName());
//获取文件的绝对路径
System.out.println(file.getAbsolutePath());
//获取文件的父路径名称,如果文件的路径中只包含文件名称,则显示空
System.out.println(file.getParent());
//返回文件绝对路径的规范格式
System.out.println(file.getCanonicalPath());
//返回操作系统的文件分割符
System.out.println(File.separator);
//无论当前文件是否存在,只要给定具体的路径,都可以返回相应的路径名称
File file2 = new File("c:/a/b/c");
System.out.println(file2.getAbsolutePath());
//判断文件是否是文件或者目录
System.out.println(file2.isDirectory());
System.out.println(file2.isFile());
// String[] list = file2.list();
// for(String str:list){
// System.out.println(list.toString());
// }
// System.out.println("---------------");
// File[] files = file2.listFiles();
// for(File f : files){
// System.out.println(f);
// }
//打印当前文件系统的所有盘符
File[] files1 = File.listRoots();
for(int i = 0;i<files1.length;i++){
System.out.println(files1[i]);
}
//创建单级目录
file2.mkdir();
//创建多级目录
file2.mkdirs();
//循环遍历输出C盘中的所有文件的绝对路径
//使用递归的方式
printFile(new File("D:\\Github\\javase"));
}
/**
*
* 文件在遍历的时候,会出现空指针的问题,原因在于当前文件系统受保护,某些文件没有访问权限,此时会报空指针异常
* @param file
*/
public static void printFile(File file){
if(file.isDirectory()){
File[] files = file.listFiles();
for(File f:files){
printFile(f);
}
}else{
System.out.println(file.getAbsolutePath());
}
}
}
/**
* 实现多线程的时候:
* 1、需要继承Thread类
* 2、必须要重写run方法,指的是核心执行的逻辑
* 3、线程在启动的时候,不要直接调用run方法,而是要通过start()来进行调用
* 4、每次运行相同的代码,出来的结果可能不一样,原因在于多线程谁先抢占资源无法进行人为控制
* 第二种实现方式:使用了代理设计模式
* 1、实现Runnable接口
* 2、重写run方法
* 3、创建Thread对象,将刚刚创建好的runnable的子类实现作为thread的构造参数
* 4、通过thread.start()进行启动
* 两种实现方式哪种用的比较多
* 推荐使用第二种方式,
* 1、java是单继承,将继承关系留给最需要的类
* 2、使用runnable接口之后不需要给共享变量添加static关键字,每次创建一个对象,作为共享对象即可
* 线程的生命周期:
* 1、新生状态:
* 当创建好当前线程对象之后,没有启动之前(调用start方法之前)
* ThreadDemo thread = new ThreadDemo()
* RunnableDemo run = new RunnableDemo()
* 2、就绪状态:准备开始执行,并没有执行,表示调用start方法之后
* 当对应的线程创建完成,且调用start方法之后,所有的线程会添加到一个就绪队列中,所有的线程同时去抢占cpu的资源
* 3、运行状态:当当前进程获取到cpu资源之后,就绪队列中的所有线程会去抢占cpu的资源,谁先抢占到谁先执行,在执行的过程中就叫做运行状态
* 抢占到cpu资源,执行代码逻辑开始
* 4、死亡状态:当运行中的线程正常执行完所有的代码逻辑或者因为异常情况导致程序结束叫做死亡状态
* 进入的方式:
* 1、正常运行完成且结束
* 2、人为中断执行,比如使用stop方法
* 3、程序抛出未捕获的异常
* 5、阻塞状态:在程序运行过程中,发生某些异常情况,导致当前线程无法再顺利执行下去,此时会进入阻塞状态,进入阻塞状态的原因消除之后,
* 所有的阻塞队列会再次进入到就绪状态中,随机抢占cpu的资源,等待执行
* 进入的方式:
* sleep方法
* 等待io资源
* join方法(代码中执行的逻辑)
*
* 注意:
* 在多线程的时候,可以实现唤醒和等待的过程,但是唤醒和等待操作的对应不是thread类
* 而是我们设置的共享对象或者共享变量
* 多线程并发访问的时候回出现数据安全问题:
* 解决方式:
* 1、同步代码块
* synchronized(共享资源、共享对象,需要是object的子类){具体执行的代码块}
* 2、同步方法
* 将核心的代码逻辑定义成一个方法,使用synchronized关键字进行修饰,此时不需要指定共享对象
*
*/
public class HowToCreateThread {
static class MyThread extends Thread {
@Override
public void run() {
System.out.println("Hello MyThread!");
}
}
static class MyRun implements Runnable {
@Override
public void run() {
System.out.println("Hello MyRun!");
}
}
public static void main(String[] args) {
new MyThread().start();
new Thread(new MyRun()).start(); //使用Runnable接口时候, 必须把类名new MyRun()传入Thread中
new Thread(()->{
System.out.println("Hello Lambda!");
}).start();
}
}
Sleep方法:
package NewThreadDemon;
public class SleepTest {
public void testSleep(){
for (int i = 0; i < 100; i++) {
System.out.println("A"+i);
}
}
public void testYied(){
for (int i = 0; i < 100; i++) {
System.out.println("B"+i);
if (i%10 == 0)
Thread.yield();
}
}
}
package NewThreadDemon;
public class TestMain {
public static void main(String[] args) {
SleepTest sleepTest = new SleepTest();
//lambda 表达式
new Thread(()->{
sleepTest.testSleep();
try {
Thread.sleep(500);
}
catch (InterruptedException e)
{
e.printStackTrace();
}
}).start();
new Thread(()->{
sleepTest.testYied();
}).start();
}
}
线程池
只有一个线程池的线程池
public static void main(String[] args) {
ExecutorService service = Executors.newSingleThreadExecutor();
for(int i=0; i<5; i++) {
final int j = i;
service.execute(()->{
System.out.println(j + " " + Thread.currentThread().getName());
});
}
}
带弹性的线程池, 来一个任务起一个线程
public static void main(String[] args) throws InterruptedException {
ExecutorService service = Executors.newCachedThreadPool();
System.out.println(service);
for (int i = 0; i < 2; i++) {
service.execute(() -> {
try {
TimeUnit.MILLISECONDS.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName());
});
}
System.out.println(service);
TimeUnit.SECONDS.sleep(80);
System.out.println(service);
}
固定个数的线程池newFixedThreadPool
public static void main(String[] args) throws InterruptedException, ExecutionException {
long start = System.currentTimeMillis();
getPrime(1, 200000);
long end = System.currentTimeMillis();
System.out.println(end - start);
final int cpuCoreNum = 4;
ExecutorService service = Executors.newFixedThreadPool(cpuCoreNum);
MyTask t1 = new MyTask(1, 80000); //1-5 5-10 10-15 15-20
MyTask t2 = new MyTask(80001, 130000);
MyTask t3 = new MyTask(130001, 170000);
MyTask t4 = new MyTask(170001, 200000);
Future<List<Integer>> f1 = service.submit(t1);
Future<List<Integer>> f2 = service.submit(t2);
Future<List<Integer>> f3 = service.submit(t3);
Future<List<Integer>> f4 = service.submit(t4);
start = System.currentTimeMillis();
f1.get();
f2.get();
f3.get();
f4.get();
end = System.currentTimeMillis();
System.out.println(end - start);
}
static class MyTask implements Callable<List<Integer>> {
int startPos, endPos;
MyTask(int s, int e) {
this.startPos = s;
this.endPos = e;
}
@Override
public List<Integer> call() throws Exception {
List<Integer> r = getPrime(startPos, endPos);
return r;
}
}
static boolean isPrime(int num) {
for(int i=2; i<=num/2; i++) {
if(num % i == 0) return false;
}
return true;
}
static List<Integer> getPrime(int start, int end) {
List<Integer> results = new ArrayList<>();
for(int i=start; i<=end; i++) {
if(isPrime(i)) results.add(i);
}
return results;
}
定时器线程池, 一般不用 用quartz timer
public static void main(String[] args) {
ScheduledExecutorService service = Executors.newScheduledThreadPool(4);
service.scheduleAtFixedRate(()->{
try {
TimeUnit.MILLISECONDS.sleep(new Random().nextInt(1000));
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName());
}, 0, 500, TimeUnit.MILLISECONDS);
}
public static void main(String[] args) throws IOException {
ExecutorService service = Executors.newWorkStealingPool();
System.out.println(Runtime.getRuntime().availableProcessors());
service.execute(new R(1000));
service.execute(new R(2000));
service.execute(new R(2000));
service.execute(new R(2000)); //daemon
service.execute(new R(2000));
//由于产生的是精灵线程(守护线程、后台线程),主线程不阻塞的话,看不到输出
System.in.read();
}
static class R implements Runnable {
int time;
R(int t) {
this.time = t;
}
@Override
public void run() {
try {
TimeUnit.MILLISECONDS.sleep(time);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(time + " " + Thread.currentThread().getName());
}
}