1.线程的创建
1.1Thread类实现多线程
package etc.sdut.edu.cn;
public class Mythread extends Thread{
@Override
public void run() {
for(int i =0 ; i<100 ; i++)
{
System.out.println(Thread.currentThread().getName()+"--"+i);
}
}
}
1.2 Runnable接口实现多线程
package etc.sdut.edu.cn;
public class Myrunnable implements Runnable{
@Override
public void run() {
for(int i = 0 ; i<100 ;i++)
{
System.out.println(Thread.currentThread().getName()+"--"+i);
}
}
}
1.3主线程
package etc.sdut.edu.cn;
import java.io.FileNotFoundException;
import java.io.PrintStream;
public class XCtest {
public static void main(String[] args) throws FileNotFoundException {
//输出重定向
System.setOut(new PrintStream(".\\src\\te.txt"));
//主线程
for(int i = 0 ; i<100 ; i++)
{
System.out.println(Thread.currentThread().getName()+"--"+i);
}
//准备线程
Mythread mthread = new Mythread() ;
Myrunnable ythread = new Myrunnable() ;
//将线程运行起来
Thread thread = new Thread(ythread) ;
thread.start();
mthread.start();
System.out.println("main.........");
}
}
2.线程的一些方法
package etc.sdut.edu.cn;
import java.io.FileNotFoundException;
import java.io.PrintStream;
public class XCtest {
public static void main(String[] args) throws FileNotFoundException {
//输出重定向
System.setOut(new PrintStream(".\\src\\te.txt"));
//准备线程
Mythread mthread = new Mythread();
Myrunnable ythread = new Myrunnable();
//将线程运行起来
Thread thread = new Thread(ythread) ;
thread.start();
mthread.start();
//主线程
for(int i = 0 ; i<100 ; i++)
{
System.out.println(Thread.currentThread().getName()+"--"+i);
if(i == 50)
{
//Thread.yield();//让步直到该线程执行完成
try {
thread.join();//插队
//thread.join(1000) ;//控制插队的时间
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
System.out.println("main.........");
}
}
3.解决线程安全性问题
实例 买票问题和消费者和生产者的问题
买票问题:
package etc.sdut.edu.cn;
public class Trickrunnable implements Runnable{
private int count = 1000 ;
@Override
public void run() {
while(count>0)
{
System.out.println(Thread.currentThread().getName()+"--"+(1001-count));
count--;
}
}
}
package etc.sdut.edu.cn;
import java.io.FileNotFoundException;
import java.io.PrintStream;
public class Trick {
//卖一千张票
public static void main(String[] args) throws FileNotFoundException {
System.setOut(new PrintStream(".\\src\\te.txt"));
Trickrunnable a = new Trickrunnable() ;
//准备窗口
Thread thread = new Thread(a,"窗口1") ;
Thread thread1 = new Thread(a,"窗口2") ;
//运行线程
thread.start();
thread1.start();
}
}
但上述的代码会出现线程安全的问题
有以下解决方案
1.可以添加控制条件来使线程的运行变得正常
package etc.sdut.edu.cn;
public class Trickrunnable implements Runnable{
private int count = 1000 ;
@Override
public void run() {
while(count>0)
{
System.out.println(Thread.currentThread().getName()+"--"+(1001-count));
count--;
}
}
}
这样就不会出现卖重票的事情了
也可以通过多线程同步来接决这个问题
1.同步代码块
package etc.sdut.edu.cn;
import java.io.FileNotFoundException;
import java.io.PrintStream;
public class Trick {
//卖一千张票
public static void main(String[] args) throws FileNotFoundException {
System.setOut(new PrintStream(".\\src\\te.txt"));
Trickrunnable a = new Trickrunnable() ;
//准备窗口
Thread thread = new Thread(a,"窗口1") ;
Thread thread1 = new Thread(a,"窗口2") ;
//运行线程
thread.start();
thread1.start();
}
}
2.同步方法
package etc.sdut.edu.cn;
public class Trickrunnable implements Runnable{
private int count = 1000 ;
@Override
public void run() {
while(count>0)
k();
}
private synchronized void k() {
System.out.println(Thread.currentThread().getName()+"--"+(1001-count));
count--;
}
}
3.同步锁
package etc.sdut.edu.cn;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
public class Trickrunnable implements Runnable{
private int count = 1000 ;
private final Lock lock = new ReentrantLock() ; //这里使用final是为了保持这个对象不变
@Override
public void run() {
while(count>0)
{
lock.lock();//锁住
System.out.println(Thread.currentThread().getName()+"--"+(1001-count));
count--;
lock.unlock();//解锁
}
}
}
实例2:生产者和消费者
package etc.sdut.edu.cn;
//容器
public class Conntainer {
private int count = 0 ;//记录产品数量
//下面是生产者和消费者的两个同步方法
//规定为了让生产者有时间来休息只要count==10就可以休息
public synchronized void pop()
{
this.notify();//唤醒沉睡的线程
//如果超出数量就让生产者来休息
while(count>=10)
{
try {
System.out.println(Thread.currentThread().getName()+"累了");
this.wait();//让当前线程休息
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
count++ ;
System.out.println(Thread.currentThread().getName()+"生产产品"+count);
}
public synchronized void push()
{
this.notify();
while(count<0)
{
System.out.println(Thread.currentThread().getName()+"不高兴");
try {
this.wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
count-- ;
System.out.println(Thread.currentThread().getName()+"消费了"+count);
}
}
package etc.sdut.edu.cn;
public class Pop extends Thread{
Conntainer conntainer ;
public Pop(Conntainer conntainer ,String name) {
super(name);
this.conntainer = conntainer;
this.start();
}
@Override
public void run() {
while(true)
{
conntainer.pop();
}
}
}
package etc.sdut.edu.cn;
public class Push extends Thread{
Conntainer conntainer ;
public Push(Conntainer conntainer ,String name) {
super(name);
this.conntainer = conntainer;
this.start();
}
@Override
public void run() {
while(true)
{
conntainer.push();
}
}
}
package etc.sdut.edu.cn;
public class Main {
public static void main(String[] args) {
Conntainer conntainer = new Conntainer() ; //准备好容器
Pop push = new Pop(conntainer,"生产者") ;
Push pop1 = new Push(conntainer,"消费者1") ;
Push pop2 = new Push(conntainer,"消费者2") ;
}
}