Java线程的一些方法使用
目录:
Thread
Runnable
InnerClass
Synchronized
Lock
Wait() 和 Notify() 两种方法
ThreadPool
lambda
Thread
getName() 、setName 和 currentThread()
public class Demo02 {
public static void main(String[] args) {
Mythread02 t1 = new Mythread02();//创建一个线程
t1.start();//开启一个线程
new Mythread02("小张").start();//匿名内部类创建线程并执行
/*
IllegalThreadStateException:重复启动异常
t1.setName("小庄");
t1.start();*/
Mythread02 t2 = new Mythread02();
t2.setName("小庄");//线程重命名
t2.start();
System.out.println(Thread.currentThread().getName());//获取当前正在执行的线程的名字
//currentThread()获取当前正在执行的线程
}
}
public class Mythread02 extends Thread{
public Mythread02(){
}
public Mythread02(String name) {
super(name);//构造方法,设置线程名称
}
@Override
public void run() {
System.out.println(Thread.currentThread().getName());
}
}
Runnable
Thread(Runnable target) 和 Thread(Runnable target, String name)方法
public class Demo02 {
public static void main(String[] args) {
RunableImpl02 ri2 = new RunableImpl02();//创建一个Runnable接口的实现类对象
Thread t1 = new Thread(ri2);//传入Runnable接口的实现类对象
t1.start();
RunableImpl02 rip3 = new RunableImpl02();
Thread t2 = new Thread(rip3,"线程");//传入接口的实现类对象并设置线程名称
t2.start();
}
}
public class RunableImpl02 implements Runnable{
@Override
public void run() {
for (int i = 0; i < 10; i++) {
System.out.println(Thread.currentThread().getName() + "--->" + i);
}
}
}
InnerClass
public class Demo02 {
public static void main(String[] args) {
Runnable r = new Runnable() {//创建匿名内部类接口
@Override
public void run() {//重写run方法
for (int i = 0; i < 10; i++) {
System.out.println(Thread.currentThread().getName()+"-->"+i);
}
}
};
new Thread(r).start();
new Thread(new Runnable() {
@Override
public void run() {
for (int i = 0; i < 10; i++) {
System.out.println(Thread.currentThread().getName() +"===" + i);
}
}
}).start();
}
}
Synchronized
使用同步代码锁
同步使用的锁对象必须保证唯一
public class Demo01Ticket {
public static void main(String[] args) {
Runnableimpl r = new Runnableimpl();
//Runnableimp2 r = new Runnableimp2();
Thread t1 = new Thread(r);
Thread t2 = new Thread(r);
Thread t3 = new Thread(r);
//创建三个线程并执行
t1.start();
t2.start();
t3.start();
}
}
public class Runnableimpl implements Runnable{
private int ticket = 20;//三个线程共同来买这20张票
Object obj = new Object();//创建一个锁对象
@Override
public void run() {
while(true){//使用死循环,让卖票操作重复执行
synchronized(obj){//同步代码块
if (ticket >0){
try {
Thread.sleep(10);//提高安全问题出现的概率,让程序睡眠
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName()+"-->正在卖 第"+ticket+"张票" );
ticket--;
}
}
/*
同步的实现原理:
同步中的线程,没有执行完毕不会释放锁
同步外的线程,没有锁对象obj进不去同步
*/
}
}
}
使用同步方法
//main方法用前面的Demo01Ticket
public class RunnableImpl2 implements Runnable{
private int ticket = 20;
Object obj = new Object();//创建锁对象
@Override
public void run() {
System.out.println("this:" + this);//普通方法中,this是传入的Runnable接口实现类
while(true) {
PayTicket();
}
}
public synchronized void PayTicket(){//非静态方法,方法体内是访问了共享数据的代码
if (ticket > 0) {
try {
Thread.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + "-->正在卖第" + ticket + "张票");
ticket--;
}
}
}
//两种形式的静态方法
public class RunnableImpl3 implements Runnable{
private static int ticket = 20;
@Override
public void run() {
while(true){
payTicket();
}
}
/*public static synchronized void payTicket(){
if (ticket >0){
try {
Thread.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName()+"-->正在卖第"+ticket+"张票" );
ticket--;
}
}*/
//锁对象是什么?不能是this,this是创建对象之后产生的,静态方法优先于对象,静态方法的锁对象是本类的class属性-->class文件对象(反射)
public static void payTicket(){
synchronized(RunnableImpl3.class){//方法体内部是访问了共享数据的代码
if (ticket >0) {
try {
Thread.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + "-->正在卖第" + ticket + "张票");
ticket--;
}
}
}
}
Lock
void lock()获取锁,void unlock() 释放锁。
public class Demo01Ticket {
public static void main(String[] args) {
Runnableimpl r = new Runnableimpl();
Thread t1 = new Thread(r);
Thread t2 = new Thread(r);
Thread t3 = new Thread(r);
t1.start();
t2.start();
t3.start();
}
}
public class RunnableImpl4 implements Runnable{
private int ticket = 20;
Lock l = new ReentrantLock(); //1.在成员位置创建一个ReentrantLock对象
@Override
public void run() {
while(true){
l.lock();//2.在可能会出现安全问题的代码前调用Lock接口中的方法lock获取锁
if (ticket > 0){
try {
Thread.sleep(10);
System.out.println(Thread.currentThread().getName()+"--->正在卖第"+ ticket+"张票");
ticket--;
} catch (InterruptedException e) {
e.printStackTrace();
}finally{
//3.在可能会出现安全问题的代码后调用Lock接口中的方法unlock释放锁
l.unlock();//无论程序是否异常,都会把锁释放
}
}
}
}
}
Wait() 和 Notify() 两种方法
sleep(long m)方法,在毫秒值结束之后,线程睡醒进入到Runnable/Blocked状态
使用wait(long m)方法,wait方法如果在毫秒值结束之后,还没有被notify唤醒,就会自动醒来,线程睡醒进入到Runnable/Blocked状态
void notify() 唤醒在此对象监视器上等待的单个线程。
void notifyAll() 唤醒在此对象监视器上等待的所有线程。
public class Demo01 {
public static void main(String[] args) {
Object obj = new Object();//创建锁对象,保证唯一
new Thread(new Runnable() {//匿名内部类接口重写run方法
@Override
public void run() {
while (true) {
synchronized (obj) {
System.out.println("告诉老板要吃的包子种类和数量");
try {
obj.wait();//线程进入无线等待状态,需要notify方法来唤醒
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("包子已经做好了,可以开吃了!");
System.out.println("=================================");
}
}
}
}).start();
new Thread(new Runnable() {
@Override
public void run() {
while(true){
try {
Thread.sleep(1000);//线程进入休眠状态,休眠1000毫秒
} catch (InterruptedException e) {
e.printStackTrace();
}
synchronized(obj) {
System.out.println("包子铺把您的包子准备好了");
obj.notify();
}
}
}
}).start();
}
}
ThreadPool
java.util.concurrent.Executors:线程池的工厂类,用来生成线程池。
static ExecutorService newFixedThreadPool(int nThreads) :创建一个可重用固定线程数的线程池。
submit(Runnable task) :提交一个 Runnable 任务用于执行。
void shutdown():关闭/销毁线程池的方法
public class Demo01 {
public static void main(String[] args) {
ExecutorService es = Executors.newFixedThreadPool(2);//创建一个线程池的工厂类,可生产两个线程
//创建新线程
es.submit(new RunnableImpl());
es.submit(new RunnableImpl());
es.submit(new RunnableImpl());//线程池会一直开启,使用完了线程,会自动把线程归还给线程 池,线程可以继续使用
es.shutdown();//销毁线程池
es.submit(new RunnableImpl());//抛异常RejectedExecutionException,线程池都没有了, 就不能获取线程了
}
}
/*控制台输出:
pool-1-thread-1创建一个线程对象
pool-1-thread-2创建一个线程对象
pool-1-thread-1创建一个线程对象
*/
public class RunnableImpl implements Runnable{
@Override
public void run() {
System.out.println(Thread.currentThread().getName()+"线程执行");
}
}
lambda
格式 : (参数列表) -> {一些重写方法的代码};
() : 接口中抽象方法的参数列表,没有参数,就空着;有参数就写出参数,多个参数使用逗号分隔
-> : 传递的意思,把参数传递给方法体{}
{} : 重写接口的抽象方法的方法体
public class Demo01 {
public static void main(String[] args) {
//创建Runnable接口的实现类
RunnableImpl runnable = new RunnableImpl();
Thread t1 = new Thread(runnable);
t1.start();
//创建Runnable接口的实现类
Runnable r = new Runnable(){
@Override
public void run() {
System.out.println(Thread.currentThread().getName() + "线程执行");
}
};
new Thread(r).start();
//Runnable接口的匿名内部类
new Thread(new Runnable() {
@Override
public void run() {
System.out.println(Thread.currentThread().getName() + "线程执行");
}
}).start();
//lambda表达式
new Thread(() ->{
System.out.println(Thread.currentThread().getName() + "线程执行");
}).start();
//lambda表达式的简写
new Thread(()-> System.out.println(Thread.currentThread().getName() + "线程执 行")).start();
}
}
public class RunnableImpl implements Runnable{
@Override
public void run() {
System.out.println(Thread.currentThread().getName()+"线程执行");
}
}