学习Java的22天

这篇博客介绍了Java中的多线程实现,包括通过继承Thread类和实现Runnable接口的方式。详细阐述了run()和start()方法的区别,并展示了线程控制的sleep()方法。此外,还讲解了线程安全问题的解决方案——使用synchronized同步代码块,以及实现线程安全的重要性。
摘要由CSDN通过智能技术生成

一、单线程

主线程 执行main方法的线程
单线程程序:只有一个线程在执行,从头到尾

多线程的实现方案有两种

继承Thread类
实现Runnable接口

1.继承Thread类

在这里插入图片描述

实现步骤:

1.创建一个Thread类的子类
2.在Thread子类中重写run方法,设置线程任务(干什么)
3.创建Thread子类的对象
4.调用Thread类中的方法start来启动线程,执行run方法
在这里插入图片描述

run()方法和start()方法的区别?

run():封装线程执行的代码,直接调用,相当于普通方法的调用
start():启动线程;然后由JVM调用此线程的run()方法

2.设置和获取线程名称

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

3.线程控制

static void sleep(longmillis) 使当前正在执行的线程停留(暂停执行)指定的毫秒数

package demo03;

public class Demo03Sleep {
public static void main(String[] args) {
for(int i=1;i<10;i++) {
System.out.println(i);

		try {
			Thread.sleep(1000);
		} catch (InterruptedException e) {
			// TODO 自动生成的 catch 块
			e.printStackTrace();
		}
	}
}

}
在这里插入图片描述

4.Runnable

实现步骤
定义一个类MyRunnable实现Runnable接口
在MyRunnable类中重写run()方法
创建MyRunnable类的对象
创建Thread类的对象,把MyRunnable对象作为构造方法的参数
启动线程
实现runnable接口创建多线程的好处:

  • 1.避免了单继承的局限性
  • 2.增强了程序的扩展性,降低了程序的耦合性
    在这里插入图片描述

5.synchronized

解决线程安全问题的一种方案:使用同步代码块
格式:
synchronized(锁对象){
可能会出现线程安全的代码(是因为访问了共享的数据)
}
注意:
1.通过代码块中的锁对象,可以使用任意的对象
2.但是必须保证多个线程使用的锁对象是同一个
3.锁对象作用:
把同步代码块锁起来,只让一个线程执

代码

package Demo01;
/*/

  • 主线程 执行main方法的线程
  • 单线程程序:只有一个线程在执行,从头到尾
    */
    public class demo01MAainThread {
    public static void main(String[] args) {
    Person p1=new Person(“小强”);
    p1.run();
    //System.out.println(0/0);
    Person p2=new Person(“小明”);
    p2.run();
    }

}

package Demo01;
/*/

  • java.long.Thread

  • 实现步骤:

  • 1.创建一个Thread类的子类

  • 2.在Thread子类中重写run方法,设置线程任务(干什么)

  • 3.创建Thread子类的对象

  • 4.调用Thread类中的方法start来启动线程,执行run方法
    */
    public class Demo01Thread {
    public static void main(String[] args) {
    //3.创建子类对象
    MyThread mt=new MyThread();
    //4.调用start方法
    mt.start();

     for(int i=0;i<20;i++) {
     	System.out.println("主线程: "+i);
     	//if(i==10)
     		//System.out.println(0/0);
     }
    

    }

}
package Demo01;
/*/

  • 创建thread子类

  • 重写run方法
    */
    public class MyThread extends Thread{
    public void run() {
    for(int i=0;i<20;i++) {
    System.out.println("子线程: "+i);
    }

    }

}
package Demo01;

public class Person {
private String name;

public String getName() {
	return name;
}

public void setName(String name) {
	this.name = name;
}

public Person(String name) {
	
	this.name = name;
}
public void run() {
	for(int i=0;i<20;i++)
	{
		System.out.println(name+"-->"+i);
	}
}

}
package demo02;
/*/

  • java.long.Thread

  • 实现步骤:

  • 1.创建一个Thread类的子类

  • 2.在Thread子类中重写run方法,设置线程任务(干什么)

  • 3.创建Thread子类的对象

  • 4.调用Thread类中的方法start来启动线程,执行run方法
    */
    public class Demo01Thread {
    public static void main(String[] args) {
    //3.创建子类对象
    MyThread mt=new MyThread();
    //4.调用start方法
    mt.start();

     new MyThread().start();
     new MyThread().start();
     new MyThread().start();
     
     System.out.println("main: "+Thread.currentThread().getName());
    

    }

}
package demo02;

public class Demo02ThreadSetName {
public static void main(String[] args) {
MyThreadName mt=new MyThreadName(“小强”);
mt.start();
new MyThreadName(“旺财”).start();
}

}
package demo02;
/*/

  • 创建thread子类
  • 重写run方法
    */
    public class MyThread extends Thread{
    public void run() {
    //String name=getName();
    //System.out.println("run: "+name);
    System.out.println(“子”+Thread.currentThread().getName());
    }

}
package demo02;

public class MyThreadName extends Thread {
public MyThreadName() {}
public MyThreadName(String name) {
super(name);//把线程的名字传递给父类,
}

public void run() {
	//String name=getName();
	//System.out.println("run: "+name);
	System.out.println("子: "+Thread.currentThread().getName());
}

}
package demo03;

public class Demo03Sleep {
public static void main(String[] args) {
for(int i=1;i<10;i++) {
System.out.println(i);

		try {
			Thread.sleep(1000);
		} catch (InterruptedException e) {
			// TODO 自动生成的 catch 块
			e.printStackTrace();
		}
	}
}

}
package demo04;
/*/

  • 实现runnable接口创建多线程的好处:

  • 1.避免了单继承的局限性

  • 2.增强了程序的扩展性,降低了程序的耦合性
    */
    public class Demo04Runnable {
    public static void main(String[] args) {
    //3.创建一个runnable接口的实现类对象
    //RunnableImpl run=new RunnableImpl();
    //4.创建Thread类对象,构造方法中传递Runnable接口实现类对象
    //Thread t= new Thread(run);
    //5.调用Thread类中的start方法,启动子线程
    Thread t=new Thread(new RunnableImpl2());
    t.start();
    for(int i=0;i<20;i++) {
    System.out.println(Thread.currentThread().getName()+"–>"+i);
    }
    }
    }
    package demo04;
    //1.创建一个runnable接口的实现类
    //2.在实现类中,重写runnable中的run方法,设置线程任务
    public class RunnableImpl implements Runnable {

    @Override
    public void run() {
    // TODO 自动生成的方法存根
    for(int i=0;i<20;i++) {
    System.out.println(Thread.currentThread().getName()+"–>"+i);
    }
    }

}package demo04;

public class RunnableImpl2 implements Runnable {
public void run() {
// TODO 自动生成的方法存根
for(int i=0;i<20;i++) {
System.out.println(“Helloworld”+i);
}

}
}
package demo05;

public class Demo01Ticket {
public static void main(String[] args) {
RunnableImpl run =new RunnableImpl();
Thread t0= new Thread(run);
Thread t1= new Thread(run);
Thread t2= new Thread(run);
t0.start();
t1.start();
t2.start();
}

}
package demo05;
/*/

  • 解决线程安全问题的一种方案:使用同步代码块
  • 格式:
  • synchronized(锁对象){
  •         可能会出现线程安全的代码(是因为访问了共享的数据)
    
  •         }
    
  •         注意:
    
  •         1.通过代码块中的锁对象,可以使用任意的对象
    
  •         2.但是必须保证多个线程使用的锁对象是同一个
    
  •         3.锁对象作用:
    
  •         把同步代码块锁起来,只让一个线程执行
    

*/
public class RunnableImpl implements Runnable {
private int ticket =100;
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--;
			}
		}
	}
}

}

学号

2020080605016

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值