更新时间:2018-11-26 来源:黑马程序员 浏览量:
【创建多线程的第一种方式:--继承Thread类】
1:定义一个类继承Thread类
2:重写Thread类中的run方法
3:创建该类的实例,并调用start方法。
【start方法的作用】:A、启动线程。B、调用run方法
1、模拟一个多线程:
class MyThread extends Thread{
public void run(){
for(int i=1;i<500;i++){
System.out.println("MyThread:"+i);
}
}
}
public class Demo1{
public Static void main(String[] args){
MyThread my = new MyThread();
my.start();
for(int j=1;j<500;j++){
System.out.println("main:"+i);
}
}
}
2、匿名内部类的线程实现方式:
public class Demo2{
public static void main(String[] args){
new Thread{
public void run(){
for(int=i;i<100;i++){
System.out.println("MyThread:"=i);
}
}
}.start;
}
for(int i=1;i<100;i++){
System.out.println("main:"+i);
}
}
3、模拟一个QQ聊天的线程:
class Video extends Thread{
public void run(){
while(true){
System.out.println("视频中...");
}
}
}
class Talk extends Thread{
public void run(){
while(true){
System.out.println("聊天中...");
}
}
}
public class Demo3{
public static void main(String[] args){
Video v = new Video();
Talk t = new Video();
v.start();
t.start();
for(int i=1;i<100;i++){
System.out.println("main:"+i);
}
}
}
-------------------------------------------------------------------------------------------------------
【创建线程的第二种方式:--实现Runnable接口】
1、实现Runnable接口
2、重写Runnable接口中的run方法
3、将Runnable接口中的子类对象作为实际参数,传递给Thread类的构造方法
4、调用Thread类中的start方法开启线程
1、public class Demo1{
public static void main(String[] args){
MyRun my = new MyRun();
Thread t = new Thread(my);
t.start();
for(int i=1;i<100;i++){
System.out.println("main:"+i);
}
}
}
class MyRun implements Runnable{
public void run(){
for(int i=1;i<100;i++){
System.out.println("MyRun:"+i);
}
}
}
2、模拟卖票系统【实现Runnable接口】
public class Demo{
public static void main(String[] args){
MyRunTick mt = new MyRunTick();
Thread t1 = new Thread(mt,"一号窗口");
Thread t2 = new Thread(mt,"二号窗口");
Thread t3 = new Thread(mt,"三号窗口");
Thread t4 = new Thread(mt,"四号窗口");
t1.start();
t2.start();
t3.start();
t4.start();
}
}
class MyRunTicket implements Runnable{
private int ticket = 100;
public void run(){
while(true){
synchronized(this){
if(ticket > 0){
System.out.println(Thread.currentThread().getName()+"卖:"+this.ticket+"号票");
try{
Thread.sleep(1);
}catch(InterruptedException e){
e.printStackTrace();
}
ticket--;
}else{
System.out.println(Thread.currentThread().getName()+"票已卖完。。");
break;
}
}
}
}
}
总结:同步的前提是必须有两个或者两个以上的线程,多个线程使用的是同一个锁。
线程同步的前提:1、必须是多个线程使用同一个锁;
2、必须保证同步中只能有一个线程在运行
-------------------------------------------------------------------------------------------------------
1、实现方式和继承方式有什么区别?
实现的好处是:避免了单继承的局限性。---->> 定义线程的时候最好使用实现方式
区别是:继承Thread线程的代码存放在Thread子类的run()方法中;
实现Runnable线程的代码存放在接口子类的run()方法中。
2、什么是锁对象?如何创建?如何获得?
每个Java对象都有一个锁对象,而且只有一把钥匙;
可以使用this关键字作为锁对象,也可以使用所在类的字节码文件对应的Class对象作为锁对象;
可以通过:类名.class 或者 对象.Class() 获得。
3、同步的使用?
只能同步方法(代码块),不能同步类或者变量。
4、如何解决《生产者与消费者》的问题?
可以通过一个标记,表示数据的存储空间状态。
【代码如下:】
pulibc class Demo{
public static void main(String[] args){
Persion p = new Person();
Producer pro = new Prodecer();
Consumer con = new Consumer();
Thread t1 = new Thread(pro,"生产者");
Thread t2 = new Thread(con,"消费者");
t1.start();
t2.start();
}
}
// 使用Person作为数据存储空间
class Person{
String name;
String gender;
boolean flag = false;
public synchronized void set(String name,String gender){
if(flag){
try{
wait();
}catch(InterruptedException e){
e.printStackTrace();
}
}
this.name = name;
this.gender = gender;
flag = true;
notify();
}
public synchronized void read(){
if(!flag){
try{
wait();
}catch(InterruptedException e){
e.printStackTrace();
}
}
System.out.println("name:"+this.name+"----gender:"+this.gender);
flag = false;
notify();
}
}
// 生产者
class Producer implements Runnable{
Person p;
public Producer(){
}
public Producer(Person p ){
this.p = p;
}
public void run(){
int i = 0;
while(trues){
if(i%2=0){
p.set("jack","man");
}else{
p.set("小丽","女");
}
i++;
}
}
}
// 消费者
class Consumer implements Runnable{
Person p;
public Consumer(){
}
public Consumer(Person p){
this.p = p;
}
public void run(){
while(true){
p.read();
}
}
}
5、在Object类中,wait()和sleep()有什么却别?
wait() 是Object中的方法,表示:释放资源,释放锁。
sleep()是Thread中的方法,表示:释放资源,不释放锁。
6、为什么定义了notify(),还要再定义notifyAll()?
因为如果只用notify()的话,容易出现只唤醒本方线程的情况,导致程序中的所有线程都在等待。