写入本地文件
代码 fileOutputStream
public static void main(String[] args) { String hello ="hello world"; String filePath ="text.txt"; try (FileOutputStream fileOutputStream = new FileOutputStream(filePath);) { byte[] bytes = hello.getBytes(); fileOutputStream.write(bytes); System.out.println("文件写入成功:" + filePath); } catch (FileNotFoundException e) { System.out.println("异常:找不到文件!"); } catch (IOException e) { System.out.println("异常:文件写入失败!"); }
读取本地文件
代码FileInputStream
1.InputStreamReader是对FileInputStream进行包装
2.在中国使用UTF-8
3.StringBuilder是一种特殊的string可以更好地表示字符串
4.sb.append方法:把bytes里从0到尾的数据增加到sb里边
利用while循环把文件里所有内容读出
public static void main(String[] args) { String filePath = "text.txt"; try (FileInputStream fis = new FileInputStream(filePath); InputStreamReader isr = new InputStreamReader(fis, StandardCharsets.UTF_8);) { char[] bytes = new char[1024]; StringBuilder sb = new StringBuilder(); int charlength; while ((charlength= isr.read(bytes))!=-1){ sb.append(bytes,0, charlength); } String string = sb.toString(); System.out.println("读取到的内容是" + string); } catch (IOException e) { System.out.println("文件操作异常"); }
流的概念(stream)
流的特点:单向的一维操作
线程启动
1.Thread中的run方法
public class MyThread extends Thread { @Override public void run() { System.out.println("hello world"); }
外部读取方法;:thread.start();
2.Runnable中的run方法
public class MyRunnable implements Runnable { @Override public void run() { //线程操作 System.out.println("MyRunnable hello world"); } }
==================================================
public class ThreadMain { public static void main(String[] args) { MyThread thread = new MyThread(); thread.start(); //这种写法默认在主线程运行 MyRunnable myRunnable = new MyRunnable(); myRunnable.run(); //在一个新的线程里 Thread runnableThread = new Thread(myRunnable); runnableThread.start(); }
外部读取方法
1.默认在主线程运行Runnable.run()
2.在新线程里运行
Thread runnableThread = new Thread(myRunnable); runnableThread.start();
3.Callable中的call方法
public class MyCallable implements Callable<Integer> {
@Override
public Integer call() throws Exception {
System.out.println("call 开始了");
Thread.sleep(3000);
int a= 10;
int b= 20;
int c= a+b;
return c;
}
}
=========================================
public static void main(String[] args) {
MyCallable callable = new MyCallable();
FutureTask<Integer> futureTask = new FutureTask<>(callable);
Thread thread = new Thread(futureTask);
thread.start();
try {
Integer integer = futureTask.get();
System.out.println("int="+integer);
} catch (InterruptedException e) {
throw new RuntimeException(e);
} catch (ExecutionException e) {
throw new RuntimeException(e);
}
1.sleep方法:延迟3秒
2.callable不可以用new Thread,用new FutureTask
2.利用方法futureTask.get()获取结果
Thread的常见用法
Thread thread1 = new Thread(){
@Override
public void run() {
Thread thread11 = Thread.currentThread();
long id = thread11.getId();
thread11.setName("thread1");
for (int i = 0; i < 100; i++) {
System.out.println("Thread1"+i);
}
}
};
注:currentThread方法 返回对当前正在执行的线程对象的引用。
1.thread.setname设置名字 thread.getname返回名字
2thread.getID返回ID
3.thread1.setPriority 设置优先级
thread1.setPriority(Thread.MAX_PRIORITY);
4.Thread.yield() 放弃优先级
让线程停止
利用stop方法
1.创建一个独立的包
public class StopThread extends Thread { boolean stop; @Override public void run() { //执行线程里的代码 for (int i = 0; i < Integer.MAX_VALUE; i++) { if (stop) { System.out.println("StopThread停止操作"); return; } System.out.println("StopThread i=" + i); } } public void setStop(boolean stop) { this.stop = stop; } }
main方法:
public static void main(String[] args) {
StopThread stopThread = new StopThread();
stopThread.start();
//代码StopThread.sleep(),利用try catch
try {
Thread.sleep(3000);
stopThread.setStop(true);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
2.InterruptThread中断
public void run() {
//执行线程里的代码
for (int i = 0; i < Integer.MAX_VALUE; i++) {
if (interrupted()) {
System.out.println("StopThread停止操作");
return;
}
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
System.out.println("我本来在sleep,但是我被停止操作了");
return;
}
System.out.println("StopThread i=" + i);
}
注:1.本质上跟stop没有区别,但是InterruptThread可以在try catch中释放一些资源,而stop不可以。
2.在使用sleep会产生InterruptedException中断异常要进行try catch的编写。
synchronized 同步锁
synchronization(this){
}
当多线程使用同一种代码时,当thread1进入到synchronization时会执行{}中的代码,this是一种对象锁,只有当thread1执行完后,thread2才可以继续进行代码,以此类推。
lock锁用法
private final ReentrantLock reentrantLock= new ReentrantLock();
reentrantLock.lock();
try {
}finally { reentrantLock.unlock(); //解锁
}
wait与notify
notify
、notifyAll
和 wait
是 Java 中用于多线程间通信的方法,它们都属于 Object
类的方法,用于在对象的监视器(monitor)上等待或通知线程。而 sleep
是 Thread
类的一个静态方法,用于让当前线程暂停执行一段时间。
注意:notify
、notifyAll
和 wait
都只能在同步代码快或者同步方法里被使用,意思就是他们必须在拥有某个对象所的线程里被调用。
wait
当线程需要等待某个条件成立时,可以调用 wait
方法将自己挂起,并释放当前持有的监视器锁。当其他线程改变了条件并调用 notify
或 notifyAll
时,被挂起的线程可能会被唤醒。
notify
和 notifyAll
多个线程需要等待某个条件成立才能继续执行时,可以使用 wait
将线程挂起,并在条件成立时使用 notify
或 notifyAll
唤醒等待的线程。这种做法可以让线程之间能够基于某个条件进行同步。
注意:notify
只会随机唤醒一个等待在该对象上的线程,而 notifyAll
会唤醒所有等待在该对象上的线程。
wait和sleep
- 如果你需要在多线程之间进行基于某个条件的同步和通信,使用
wait
、notify
和notifyAll
。 - 如果你只是想让当前线程暂停执行一段时间,而不涉及与其他线程的同步或通信,使用
sleep
线程池
Java提供了多种类型的线程池,newFixedThreadPool
(固定线程数线程池)、newSingleThreadExecutor
(单线程化线程池)、newCachedThreadPool
(可缓存线程池)等,它们适用于不同的使用场景。
创建一个线程池ExecutorService executorService = Executors.newFixedThreadPool(size);
public static void main(String[] args) { int size = 10; ExecutorService executorService = Executors.newFixedThreadPool(size); for (int i = 0; i < 20; i++) { int task = i; Runnable runnable = new Runnable() { @Override public void run() { System.out.println("Task" + task + "当前正在运行的线程是:" + Thread.currentThread().getName()); try { Thread.sleep(1000);//模拟工作1s } catch (InterruptedException e) { throw new RuntimeException(e); } } }; executorService.submit(runnable); } executorService.shutdown(); while (!executorService.isTerminated()) { } System.out.println("当前任务已全部完成..."); } }