全国咨询/投诉热线:400-618-9090

首页技术文章正文

多线程的总结与常见问题解析

更新时间: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()的话,容易出现只唤醒本方线程的情况,导致程序中的所有线程都在等待。



作者:黑马程序员JavaEE培训学院

首发: http://java.itheima.com

javaee

python

web

ui

cloud

test

c

netmarket

pm

Linux

movies

robot

http://www.itcast.cn/subject/uizly/index.shtml?seozxuids

14天免费试学

基础班入门课程限时免费

申请试学名额

15天免费试学

基础班入门课程限时免费

申请试学名额

15天免费试学

基础班入门课程限时免费

申请试学名额

15天免费试学

基础班入门课程限时免费

申请试学名额

20天免费试学

基础班入门课程限时免费

申请试学名额

8天免费试学

基础班入门课程限时免费

申请试学名额

20天免费试学

基础班入门课程限时免费

申请试学名额

5天免费试学

基础班入门课程限时免费

申请试学名额

0天免费试学

基础班入门课程限时免费

申请试学名额

12天免费试学

基础班入门课程限时免费

申请试学名额

5天免费试学

基础班入门课程限时免费

申请试学名额

5天免费试学

基础班入门课程限时免费

申请试学名额

10天免费试学

基础班入门课程限时免费

申请试学名额
在线咨询 我要报名